用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 相关文章推荐
一个可以删除字符串中HTML标记的PHP函数
Oct 09 PHP
php图片验证码代码
Mar 27 PHP
php checkbox 取值详细说明
Aug 19 PHP
php安全开发 添加随机字符串验证,防止伪造跨站请求
Feb 14 PHP
PHP使用in_array函数检查数组中是否存在某个值
Mar 25 PHP
PHP中通过trigger_error触发PHP错误示例
Jun 23 PHP
详解WordPress中的头像缓存和代理中的缓存更新方法
Mar 01 PHP
php 数组处理函数extract详解及实例代码
Nov 23 PHP
PHP对象相关知识总结
Apr 09 PHP
PHP给源代码加密的几种方法汇总(推荐)
Feb 06 PHP
ThinkPHP5 的简单搭建和使用详解
Nov 15 PHP
PHP面试题 wakeup魔法 Ezpop pop序列化与反序列化
Apr 11 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的curl实现get和post的代码
2008/08/23 PHP
PHP实现返回JSON和XML的类分享
2015/01/28 PHP
php正则替换处理HTML页面的方法
2015/06/17 PHP
PHP程序员简单的开展服务治理架构操作详解(一)
2020/05/14 PHP
javascript 清空form表单中某种元素的值
2009/12/26 Javascript
javascript中检测变量的类型的代码
2010/12/28 Javascript
jQuery实现点击标题输入详细信息
2013/04/16 Javascript
JavaScript通过RegExp实现客户端验证处理程序
2013/05/07 Javascript
JS/jQuery实现默认显示部分文字点击按钮显示全部内容
2013/05/13 Javascript
将json当数据库一样操作的javascript lib
2013/10/28 Javascript
jquery选择器原理介绍($()使用方法)
2014/03/25 Javascript
jQuery获取某天的农历日期并判断是否除夕或新年的方法
2016/03/01 Javascript
jQuery实现手机版页面翻页效果的简单实例
2016/10/05 Javascript
jQuery实现弹出窗口弹出div层的实例代码
2017/01/09 Javascript
vue.js实现刷新当前页面的方法教程
2017/07/05 Javascript
Vue实现滑动拼图验证码功能
2019/09/15 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
2020/12/04 Vue.js
[08:08]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY
2014/06/25 DOTA
Python3实现转换Image图片格式
2018/06/21 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
2018/12/10 Python
Python 一句话生成字母表的方法
2019/01/02 Python
python+mysql实现学生信息查询系统
2019/02/21 Python
python编写猜数字小游戏
2019/10/06 Python
使用python检查yaml配置文件是否符合要求
2020/04/09 Python
Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法
2020/05/26 Python
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
技术副厂长岗位职责
2013/12/26 职场文书
社区志愿者培训方案
2014/06/10 职场文书
电大奖学金获奖感言
2014/08/14 职场文书
学校安全工作汇报材料
2014/08/16 职场文书
干部年终考核评语
2015/01/04 职场文书
拾金不昧表扬稿
2015/01/16 职场文书
2015年计生工作总结范文
2015/04/24 职场文书
实用干货:敬酒词大全,帮你应付各种场合
2019/11/21 职场文书
openstack中的rpc远程调用的方法
2021/07/09 Python
MySQL之MyISAM存储引擎的非聚簇索引详解
2022/03/03 MySQL