用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 相关文章推荐
example1.php
Oct 09 PHP
PHP XML操作类DOMDocument
Dec 16 PHP
PHP setcookie设置Cookie用法(及设置无效的问题)
Jul 13 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
Apr 23 PHP
php无限遍历目录示例
Feb 21 PHP
php使用curl和正则表达式抓取网页数据示例
Apr 13 PHP
php生成短域名函数
Mar 23 PHP
php实现微信公众号无限群发
Oct 11 PHP
PHP getallheaders无法获取自定义头(headers)的问题
Mar 23 PHP
PHPCMS忘记后台密码的解决办法
Oct 30 PHP
总结一些PHP中好用但又容易忽略的小知识
Jun 02 PHP
php数组和链表的区别总结
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作为Shell脚本语言使用
2006/10/09 PHP
PHP spl_autoload_register实现自动加载研究
2011/12/06 PHP
PHP+jQuery 注册模块的改进(三):更新到Smarty3.1
2014/10/14 PHP
PHP之预定义接口详解
2015/07/29 PHP
javascript使用定时函数实现跳转到某个页面
2013/12/25 Javascript
跟我学Nodejs(三)--- Node.js模块
2014/05/25 NodeJs
jQuery时间轴插件使用详解
2015/07/16 Javascript
Javascript之Math对象详解
2016/06/07 Javascript
JS获取input file绝对路径的方法(推荐)
2016/08/02 Javascript
jQuery实现的放大镜效果示例
2016/09/13 Javascript
javascript 实现动态侧边栏实例详解
2016/11/11 Javascript
JavaScript获取select中text值的方法
2017/02/13 Javascript
JS实现本地存储信息的方法(基于localStorage与userData)
2017/02/18 Javascript
详解如何使用Vue2做服务端渲染
2017/03/29 Javascript
Vue.js上下滚动加载组件的实例代码
2017/07/17 Javascript
记React connect的几种写法(小结)
2018/09/18 Javascript
ES6 系列之 Generator 的自动执行的方法示例
2018/10/19 Javascript
如何修改Vue打包后文件的接口地址配置的方法
2020/04/22 Javascript
js实现缓动动画
2020/11/25 Javascript
实例讲解Python设计模式编程之工厂方法模式的使用
2016/03/02 Python
Django自定义过滤器定义与用法示例
2018/03/22 Python
pygame实现简易飞机大战
2018/09/11 Python
Python PyQt5 Pycharm 环境搭建及配置详解(图文教程)
2019/07/16 Python
Django 源码WSGI剖析过程详解
2019/08/05 Python
Perry Ellis官网:美国男士品味服装
2016/12/09 全球购物
Nike香港官网:Nike HK
2019/03/23 全球购物
北京银河万佳Java面试题
2012/03/21 面试题
心理学专业毕业生推荐信范文
2013/11/21 职场文书
汽车维修专业个人求职信范文
2014/01/01 职场文书
先进班级集体事迹材料
2014/01/30 职场文书
中国梦演讲稿开场白
2014/08/28 职场文书
2014年安全保卫工作总结
2014/11/13 职场文书
2015年毕业生个人自荐书
2015/03/24 职场文书
深入理解java.lang.String类的不可变性
2021/06/27 Java/Android
Django模型层实现多表关系创建和多表操作
2021/07/21 Python
golang实现一个简单的websocket聊天室功能
2021/10/05 Golang