用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函数utf8转gb2312编码
Dec 21 PHP
php用正则表达式匹配中文实例详解
Nov 06 PHP
php mail to 配置详解
Jan 16 PHP
php判断GIF图片是否为动画的方法
Sep 04 PHP
php去除html标记的原生函数详解
Jan 27 PHP
PHP实现多维数组转字符串和多维数组转一维数组的方法
Aug 08 PHP
php创建无限级树型菜单
Nov 05 PHP
php使用正则验证中文
Apr 06 PHP
ecshop适应在PHP7的修改方法解决报错的实现
Nov 01 PHP
php脚本守护进程原理与实现方法详解
Jul 20 PHP
PHP SESSION跨页面传递失败解决方案
Dec 11 PHP
windows系统php环境安装swoole具体步骤
Mar 04 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 echo,print,printf,sprintf函数之间的区别与用法详解
2013/11/27 PHP
PHP简单实现文本计数器的方法
2016/04/28 PHP
laravel框架中间件 except 和 only 的用法示例
2019/07/12 PHP
JavaScript 利用Cookie记录用户登录信息
2009/12/08 Javascript
一个轻量级的javascript库 pj介绍
2010/12/19 Javascript
分享精心挑选的12款优秀jQuery Ajax分页插件和教程
2012/08/09 Javascript
extjs ColumnChart设置不同的颜色实现代码
2013/05/17 Javascript
js取消单选按钮选中示例代码
2013/11/14 Javascript
用jQuery实现的智能隐藏、滑动效果的返回顶部代码
2014/03/18 Javascript
javascript trim函数在IE下不能用的解决方法
2014/09/12 Javascript
jQuery中live()方法用法实例
2015/01/19 Javascript
jQuery检查事件是否触发的方法
2015/06/26 Javascript
jQuery点击其他地方时菜单消失的实现方法
2016/04/22 Javascript
设置点击文本框或图片弹出日历控件的实现代码
2016/05/12 Javascript
jQuery下拉框的简单应用
2016/06/24 Javascript
EasyUI创建对话框的两种方式
2016/08/23 Javascript
JS碰撞运动实现方法详解
2016/12/15 Javascript
select下拉框插件jquery.editable-select详解
2017/01/22 Javascript
Angularjs自定义指令实现分页插件(DEMO)
2017/09/16 Javascript
canvas轨迹回放功能实现
2017/12/20 Javascript
vue组件与复用详解
2018/04/08 Javascript
详解vue中localStorage的使用方法
2018/11/22 Javascript
js 获取扫码枪输入数据的方法
2020/06/10 Javascript
windows10系统中安装python3.x+scrapy教程
2016/11/08 Python
python学习之matplotlib绘制散点图实例
2017/12/09 Python
python中itertools模块zip_longest函数详解
2018/06/12 Python
python多线程扫描端口(线程池)
2019/09/04 Python
Django集成celery发送异步邮件实例
2019/12/17 Python
python中resample函数实现重采样和降采样代码
2020/02/25 Python
全世界最美丽的四星和五星级酒店预订:Prestigia.com
2017/11/15 全球购物
小区的门卫岗位职责
2014/10/01 职场文书
小学生优秀评语
2014/12/29 职场文书
退休教师追悼词
2015/06/23 职场文书
小学大队长竞选稿
2015/11/20 职场文书
适合毕业生创业的项目怎么找?
2019/08/08 职场文书
python爬取网页版QQ空间,生成各类图表
2021/06/02 Python