用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 相关文章推荐
PHP4 与 MySQL 交互使用
Oct 09 PHP
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
Dec 13 PHP
使用Discuz关键词服务器实现PHP中文分词
Mar 11 PHP
通过php添加xml文档内容的方法
Jan 23 PHP
PHP高效获取远程图片尺寸和大小的实现方法
Oct 20 PHP
php递归函数怎么用才有效
Feb 24 PHP
Laravel 模型关联基础教程详解
Sep 17 PHP
thinkphp框架使用JWTtoken的方法详解
Oct 10 PHP
PHP利用缓存处理用户注册时的邮箱验证,成功后用户数据存入数据库操作示例
Dec 31 PHP
Yii框架应用组件用法实例分析
May 15 PHP
PHP日期和时间函数的使用示例详解
Aug 06 PHP
如何在Laravel之外使用illuminate组件详解
Sep 20 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 MYSQL 数据备份类
2009/06/19 PHP
MYSQL 小技巧 -- LAST_INSERT_ID
2009/11/24 PHP
PHP 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)
2012/06/07 PHP
用php简单实现加减乘除计算器
2014/01/06 PHP
使用laravel的Eloquent模型如何获取数据库的指定列
2019/10/17 PHP
JQuery1.4+ Ajax IE8 内存泄漏问题
2010/10/15 Javascript
$.ajax返回的JSON无法执行success的解决方法
2011/09/09 Javascript
基于jquery的web页面日期格式化插件
2011/11/15 Javascript
关于jQuery UI 使用心得及技巧
2012/10/10 Javascript
js模拟点击事件实现代码
2012/11/06 Javascript
JS动态调用方法名示例介绍
2013/12/18 Javascript
js用typeof方法判断undefined类型
2014/07/15 Javascript
jQuery EasyUI datagrid实现本地分页的方法
2015/02/13 Javascript
jquery输入数字随机抽奖特效的简单实现代码
2016/06/10 Javascript
AngularJS使用ng-repeat指令实现下拉框
2016/08/23 Javascript
javascript设置文本框光标的方法实例小结
2016/11/04 Javascript
bootstrap table 表格中增加下拉菜单末行出现滚动条的快速解决方法
2017/01/05 Javascript
详解支持Angular 2的表格控件
2017/01/19 Javascript
three.js快速入门【推荐】
2017/01/21 Javascript
详解用vue编写弹出框组件
2017/07/04 Javascript
JavaScript实现简易聊天对话框(加滚动条)
2020/02/10 Javascript
vue实例的选项总结
2020/06/09 Javascript
vue缓存之keep-alive的理解和应用详解
2020/11/02 Javascript
[44:43]完美世界DOTA2联赛决赛日 FTD vs GXR 第一场 11.08
2020/11/11 DOTA
python实现html转ubb代码(html2ubb)
2014/07/03 Python
Python编程语言的35个与众不同之处(语言特征和使用技巧)
2014/07/07 Python
Python生成验证码实例
2014/08/21 Python
css3实现一款模仿iphone样式的注册表单
2013/03/20 HTML / CSS
医院护士的求职信范文
2013/12/26 职场文书
普通党员个人对照检查材料
2014/09/18 职场文书
西安导游词
2015/02/12 职场文书
辛亥革命观后感
2015/06/02 职场文书
学校运动会开幕词
2016/03/03 职场文书
原生JS中应该禁止出现的写法
2021/05/05 Javascript
Redis集群新增、删除节点以及动态增加内存的方法
2021/09/04 Redis
ubuntu开机后ROS程序自启动问题
2022/12/24 Servers