2019独角兽企业重金招聘Python工程师标准>>>

题目: 设计一个栈,使得PUSH、POP以及GetMin(获取栈中最小元素)能够在常数时间内完成。

分析: 很刚开始很容易想到一个方法,那就是额外建立一个最小堆保存所有元素,这样每次获取最小元素只需要O(1)的时间。但是这样的话,PUSH和POP操作就需要O(lgn)的时间了(假定栈中元素个数为n),不符合题目的要求。 那么用1个辅助栈如何呢?

解法: 使用一个辅助栈来保存最小元素,这个解法简单不失优雅。设该辅助栈名字为minimum stack,其栈顶元素为当前栈中的最小元素。这意味着 要获取当前栈中最小元素,只需要返回minimum stack的栈顶元素即可。 每次执行push操作,检查push的元素是否小于或等于minimum stack栈顶元素。如果是,则也push该元素到minimum stack中。 当执行pop操作的时候,检查pop的元素是否与当前最小值相等。如果相同,则需要将改元素从minimum stack中pop出去。 代码: [cpp] view plain copy struct StackGetMin {
void push(int x) {
elements.push(x);
if (minStack.empty() || x <= minStack.top()) //push的元素小于当前minStack的最小元素,则push到minStack中
minStack.push(x);
}
bool pop() {
if (elements.empty()) return false;
if (elements.top() == minStack.top()) //如果原始栈栈顶元素与minStack栈顶元素相同,则将该元素也从minStack中pop出去。
minStack.pop();
elements.pop();
return true;
}
bool getMin(int &min) {
if (minStack.empty()) {
return false;
} else {
min = minStack.top();
return true;
}
}
stack<int> elements;
stack<int> minStack;
};

实例: 假定有元素3, 2, 5, 4, 2, 1依次入栈,则原始栈中元素为(1), 辅助栈中元素为(2) 1
2
4 1 5 2 2 2 3 3 (1) (2) 这样,第1次pop时,1从两个栈都pop出去;第2次pop时,2从两个栈都pop出去;第3次pop,元素4从原始栈pop出去,辅助栈不用pop;第4次pop,元素5从原始栈pop出去,辅助栈不需pop;第5次pop,元素2从两个栈pop出去;第6次pop,元素3从两个栈都pop出去。我们可以发现,每次push或者pop后,辅助栈的栈顶元素总是当前栈的最小元素。

另一解法(不用辅助栈) 另外一种解法利用存储差值而不需要辅助栈,方法比较巧妙。其中需要说明的几点: push(int elem)函数在栈中压入当前元素与当前栈中最小元素的差值,然后通过比较当前元素与当前栈中最小元素大小,并将它们中间的较小值压入。 pop()函数执行的时候,先pop出栈顶的两个值,这两个值分别是当前栈中最小值min和最后压入的元素与栈中最小值的差值diff。如果diff<0,则表示最后压入栈的元素是最小的元素,因此只需将min-diff压入栈中,并将min值返回即可。min-diff就是当前元素弹出后,栈中剩下元素的最小值。而如果diff>=0且栈不为空,则表示当前值不是最小值,所以需要在栈中压入最小值min并将diff+min返回;如果栈为空,则表示已经是最后一个数字,直接返回min即可。 [cpp] view plain copy stack<int> s;
void push(int elem)
{
if (s.empty()) {
s.push(elem);
s.push(elem);
} else {
int min = s.top();
s.pop();
s.push(elem - min);
s.push(elem < min ? elem : min);
}
}

int pop()
{
int min = s.top();
s.pop();
int diff = s.top();
s.pop();
if (diff < 0) {
s.push(min - diff);
return min;
} else {
if (!s.empty()) {
s.push(min);
return diff + min;
}
return min;
}
}

int min()
{
int min = s.top();
return min;
}

一个实例如下: clear(): [ ] push(3): [3 3] push(4): [3 1 3] push(2): [3 1 -1 2] push(5): [3 1 -1 3 2] push(1): [3 1 -1 3 -1 1] push(1): [3 1 -1 3 -1 0 1] push(6): [3 1 -1 3 -1 0 5 1] push(7): [3 1 -1 3 -1 0 5 6 1] min() --> 1; pop() --> 7: [3 1 -1 3 -1 0 5 1] min() --> 1; pop() --> 6: [3 1 -1 3 -1 0 1] min() --> 1; pop() --> 1: [3 1 -1 3 -1 1] min() --> 1; pop() --> 1: [3 1 -1 3 2] min() --> 2; pop() --> 5: [3 1 -1 2] min() --> 2; pop() --> 2: [3 1 3] min() --> 3; pop() --> 4: [3 3] min() --> 4; pop() --> 3: [ ]

参考资料: 设计包含min的栈另解

转载于:https://my.oschina.net/u/2307114/blog/844367

设计包含min函数的栈相关推荐

  1. 包含min函数的栈 python_面试题_设计包含 min函数的栈

    设计包含 min函数的栈() 定义栈的数据结构,要求添加一个 minminmin函数,能够得到栈的最小元素. 要求函数 min.push以及 pop 的时间复杂度都是 O(1). #include u ...

  2. 程序员面试题精选100题(02)-设计包含min函数的栈[数据结构]

    题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素.要求函数min.push以及pop的时间复杂度都是O(1). 分析:这是去年google的一道面试题. 我看到这道题目时,第一反应 ...

  3. 设计包含min()函数的栈

    题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素.要求函数min.push以及pop的时间复杂度都是O(1). 分析:这是去年google的一道面试题. 我看到这道题目时,第一反应 ...

  4. 设计包含min函数的栈,O(1)空间实现方法

    原址:http://blog.csdn.net/anchor89/article/details/6055412#comments 题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素 ...

  5. 包含min函数的栈JAVA实现

    /** 设计包含min 函数的栈.* 定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素.* 要求函数min.push 以及pop 的时间复杂度都是O(1).* 思路:设计栈的元素同时包 ...

  6. 【LeetCode】剑指 Offer 30. 包含min函数的栈

    [LeetCode]剑指 Offer 30. 包含min函数的栈 文章目录 [LeetCode]剑指 Offer 30. 包含min函数的栈 一.辅助栈 一.辅助栈 解题思路: 普通栈的 push() ...

  7. 剑指offer:面试题30. 包含min函数的栈

    题目:包含min函数的栈 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min.push 及 pop 的时间复杂度都是 O(1). MinStack min ...

  8. 《LeetCode力扣练习》剑指 Offer 30. 包含min函数的栈 Java

    <LeetCode力扣练习>剑指 Offer 30. 包含min函数的栈 Java 一.资源 题目: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调 ...

  9. 《剑指offer》-- 构建乘积数组、求1+2+3+...+n、不用加减乘除做加法、包含min函数的栈、用两个栈实现队列

    一.构建乘积数组: 1.题目: 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*. ...

最新文章

  1. 32.突然弹出很多IE窗口怎么办:
  2. 学习python的日常3
  3. 模型可解释性-树结构可视化
  4. Android Service完全解析,关于服务你所需知道的一切(下)
  5. android签名文件查看工具,ionic 发布android,并查看签名文件。
  6. 使用正则把数字前面的符号替换_正则表达式(一) 基本表达式
  7. 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别...
  8. 收好这份来自大厂技术大咖的“远程办公指南”
  9. linux系统--C语言程序开发的基本步骤(包含gcc的基本步骤)
  10. Swift 可选(Optionals)类型
  11. win10 系统Docker搭建设备共享平台stf(三)
  12. 聊一聊Android的第三方开发组件
  13. 物联那点事儿之自制网络温湿度计(arduino+点灯科技篇)
  14. GTP协议循序渐进(三)----通过实例了解TEID
  15. uva 10780 分解质因数
  16. [Qt]QLabel的显示圆形
  17. youtube打开显示服务器更新,youtube-dl更新出错解决办法
  18. sql 远程过程调用失败
  19. MSP430 TTP229 单片机 触摸按键 实践 51单片机 触摸键盘
  20. python爬取猫眼电影评分

热门文章

  1. NHibenate 一些自带增删改查
  2. SliverLight Web part
  3. 人生低谷时的锅底法则
  4. arm linux 识别新硬盘_Arm发布首款64位实时处理器CortexR82
  5. hdu4923 f(A,B)分段处理
  6. POJ3757 01分数规划
  7. 【数字信号处理】LTI 系统因果性与稳定性示例 ( 示例一 | 示例二 )
  8. 【C 语言】二级指针作为输入 ( 指针数组 | 复杂指针解读 )
  9. 【Java 并发编程】线程锁机制 ( 锁的四种状态 | 无锁状态 | 偏向锁 | 轻量级锁 | 重量级锁 | 锁竞争 | 锁升级 )
  10. 【Android 文件管理】分区存储 ( MediaStore 文件操作 )