用PHP解决的一个栈的面试题


Posted in PHP onJuly 02, 2014

前言

遇到一道面试题,题目大概意思如下:

使用两个普通栈实现一个特殊栈,使得pop、push、min三个函数的都是复杂度为O(1)的操作,min函数是获得当前栈的最小值。

初步想法

1.要实现min函数为(1)操作,当时第一想法是事先需要算好当前最小值,于是会想到用一个值来保存当前栈中最小值元素,然后push和pop操作的时候维护这个值。这样min,push都是O(1)了,但pop可不是,如果当前弹出的是最小值,需要从新寻找当前元素的最小值,这个就不是o(1)了。

2.而且上面方法没有用到另外一个栈,于是又想到:在一个栈中存储排好序的元素,同样在push和pop操作中维护这个有序堆栈,如图:

用PHP解决的一个栈的面试题

但是这样的话min操作是O(1),但是push、pop操作因为要维护这个有序栈,怎么也想不到一个方法可以O(1)的复杂度。

当时觉得肯定是在另一个栈中缓存最小值信息,但是不知道是因为没吃饭还是怎么地,思维就此僵住了。

正确解法

遇到问题解决不了,感觉心里很不爽,于是吃饭的时候又开始想怎么充分理由栈的特性,有效的缓存最小值信息,以便min操作使用。

栈操作最大的特性是只能操作栈顶元素,想到那用一个辅助栈缓存每次栈操作时的最小值,不是刚刚好。这样每次pop操作的时候,两边一起弹出就可以;因为辅助栈的栈顶元素最当前栈中的最小值,push操作是也只需要比较入栈元素和辅助栈栈顶元素就可以。这样push、pop、min都都O(1)操作了。如图:

用PHP解决的一个栈的面试题

文字可能没说清楚,上代码,下面是PHP的实现,通过数组来模拟堆栈。

<?php
/**
 * 使用一个辅助栈,O(1)复杂度求出栈中的最小数
 * @hack 类中通过数组来模拟堆栈
 * 
 * @author laiwenhui
 */
class strack{

  /**
   * 数据栈,存储栈数据;
   *
   * @var array
   */
  private $_arrData = array();
  /**
   * 辅助栈,存储数据组栈中每层的最下值信息;
   *
   * @var array
   */
  private $_arrMin = array();
  /**
   * 栈顶所在单元
   *
   * @var int
   */
  private $_top=-1;
  /**
   * 出栈
   * @return bool|int
   */
  public function pop(){
    if ($this->_top === -1){
      return false;
    }
    array_pop($this->_arrMin);
    $this->_top--;
    return array_pop($this->_arrData);
  }
  /**
   * 入栈
   * @param int $element
   * @return bool
   */
  public function push($element){
    $element = intval($element);
    //如果栈为空,直接入栈
    if ($this->_top === -1){
      array_push($this->_arrData, $element);
      array_push($this->_arrMin, $element);
      $this->_top++;
      return true;
    }
    //不为空,判断入栈的值是否比最小栈栈顶小
    $min = $this->_arrMin[$this->_top];
    //比较求出最小值
    $currentMin = $element < $min ? $element : $min;
    //当前栈中最小值入栈
    array_push($this->_arrMin, $currentMin);
    //数据入栈
    array_push($this->_arrData, $element);
    $this->_top++;

    return true;
  }
  /**
   * 求当前栈空间的最小值
   * @return bool|int 
   */
  public function min(){
    if ($this->_top === -1){
      return false;
    }
    return $this->_arrMin[$this->_top];
  }
}

使用如下:

$obj = new strack();

$obj->push(12);

$obj->push(56);

$obj->push(23);

$obj->push(89);

$obj->push(4);

var_dump($obj->min());

$obj->pop();

var_dump($obj->min());

$obj->push(8);

var_dump($obj->min());

输出为:

int(4)

int(12)

int(8)

OK,满足要求。

你是否有其他更好方法实现,如果有,请告诉我^_^

PHP 相关文章推荐
用PHP调用数据库的存贮过程
Oct 09 PHP
一个ubbcode的函数,速度很快.
Oct 09 PHP
利用PHP动态生成VRML网页
Oct 09 PHP
PHP执行速率优化技巧小结
Mar 15 PHP
php中get_headers函数的作用及用法的详细介绍
Apr 27 PHP
CodeIgniter生成网站sitemap地图的方法
Nov 13 PHP
php调用c接口无错版介绍
Mar 11 PHP
php自定文件保存session的方法
Dec 10 PHP
Zend Framework动作助手FlashMessenger用法详解
Mar 05 PHP
PHP最常用的正则表达式
Feb 13 PHP
PHP文件系统管理(实例讲解)
Sep 19 PHP
laravel入门知识点整理
Sep 15 PHP
函数中使用require_once问题深入探讨 优雅的配置文件定义方法推荐
Jul 02 #PHP
PHP中遇到BOM、编码导致json_decode函数无法解析问题
Jul 02 #PHP
php foreach正序倒序输出示例代码
Jul 01 #PHP
浅析ThinkPHP的模板输出功能
Jul 01 #PHP
ThinkPHP中的系统常量和预定义常量集合
Jul 01 #PHP
ThinkPHP实现多数据库连接的解决方法
Jul 01 #PHP
ThinkPHP快速入门实例教程之数据分页
Jul 01 #PHP
You might like
php统计文章排行示例
2014/03/04 PHP
详解PHP对象的串行化与反串行化
2016/01/24 PHP
PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
2019/03/11 PHP
多个js与css文件的合并方法详细说明
2012/12/26 Javascript
jcrop基本参数一览
2013/07/16 Javascript
ie 7/8不支持trim的属性的解决方案
2014/05/23 Javascript
JavaScript中双叹号!!作用示例介绍
2014/09/21 Javascript
JS逆序遍历实现代码
2014/12/02 Javascript
js实现iframe自动自适应高度的方法
2015/02/17 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
2015/09/17 Javascript
浅析JSONP技术原理及实现
2016/06/08 Javascript
大白话讲解JavaScript的Promise
2017/04/06 Javascript
关于Vue的路由权限管理的示例代码
2018/03/06 Javascript
详解React-Router中Url参数改变页面不刷新的解决办法
2018/05/08 Javascript
微信小程序动画(Animation)的实现及执行步骤
2018/10/28 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
JavaScript常用内置对象用法分析
2019/07/09 Javascript
js+html实现点名系统功能
2019/11/05 Javascript
小程序卡片切换效果组件wxCardSwiper的实现
2020/02/13 Javascript
微信小程序实现电子签名并导出图片
2020/05/27 Javascript
一个简单的python爬虫程序 爬取豆瓣热度Top100以内的电影信息
2018/04/17 Python
python二维键值数组生成转json的例子
2019/12/06 Python
详解pyinstaller生成exe的闪退问题解决方案
2020/06/19 Python
龟牌英国商店:Turtle Wax Brand Store UK
2019/07/02 全球购物
土木工程专业大学毕业生求职信
2013/10/13 职场文书
车工岗位职责
2013/11/26 职场文书
初一科学教学反思
2014/01/27 职场文书
自考毕业自我鉴定
2014/03/18 职场文书
信用社竞聘演讲稿
2014/05/16 职场文书
社区党支部承诺书
2015/04/29 职场文书
宝葫芦的秘密观后感
2015/06/11 职场文书
2016婚礼主持词开场白
2015/11/24 职场文书
详解python网络进程
2021/06/15 Python
JavaScript实现简单拖拽效果
2021/09/15 Javascript
「SHOW BY ROCK!!」“雫シークレットマインド”组合单曲MV公开
2022/03/21 日漫
win11无线投屏在哪设置? win11无线投屏功能的使用方法
2022/04/08 数码科技