计包含min函数的栈
来源:互联网 发布:mpii数据集介绍 编辑:程序博客网 时间:2024/06/08 05:11
题目:
设计一个栈,使得PUSH、POP以及GetMin(获取栈中最小元素)能够在常数时间内完成。
转自:http://blog.csdn.net/sgbfblog/article/details/7752878
分析:
很刚开始很容易想到一个方法,那就是额外建立一个最小堆保存所有元素,这样每次获取最小元素只需要O(1)的时间。但是这样的话,PUSH和POP操作就需要O(lgn)的时间了(假定栈中元素个数为n),不符合题目的要求。
那么用1个辅助栈如何呢?
解法:
使用一个辅助栈来保存最小元素,这个解法简单不失优雅。设该辅助栈名字为minimum stack,其栈顶元素为当前栈中的最小元素。这意味着
- 要获取当前栈中最小元素,只需要返回minimum stack的栈顶元素即可。
- 每次执行push操作,检查push的元素是否小于或等于minimum stack栈顶元素。如果是,则也push该元素到minimum stack中。
- 当执行pop操作的时候,检查pop的元素是否与当前最小值相等。如果相同,则需要将改元素从minimum stack中pop出去。
- 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;
- };
另一解法(不用辅助栈)
另外一种解法利用存储差值而不需要辅助栈,方法比较巧妙。其中需要说明的几点:
push(int elem)函数在栈中压入当前元素与当前栈中最小元素的差值,然后通过比较当前元素与当前栈中最小元素大小,并将它们中间的较小值压入。
pop()函数执行的时候,先pop出栈顶的两个值,这两个值分别是当前栈中最小值min和最后压入的元素与栈中最小值的差值diff。如果diff<0,则表示最后压入栈的元素是最小的元素,因此只需将min-diff压入栈中,并将min值返回即可。min-diff就是当前元素弹出后,栈中剩下元素的最小值。而如果diff>=0且栈不为空,则表示当前值不是最小值,所以需要在栈中压入最小值min并将diff+min返回;如果栈为空,则表示已经是最后一个数字,直接返回min即可。
- 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的栈另解
- 计包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min 函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 包含min函数的栈
- 从Eclipse转移到IntelliJ IDEA一点心得
- Android Studio右下角不显示当前branch名称
- 开博
- Webservice讲解
- 形意拳锻炼一点体会
- 计包含min函数的栈
- POJ 3449 判断多边形与多边形是否相交
- ubuntu 14.04 使用---vmware 安装
- adb 常用命令
- JSON.stringify的理解和使用
- Synchronized & Lock distinguish
- 实现字符数组中的单词倒序输出
- 替换SQL字段中的换行符,回车符
- 和菜鸟一起学linux总线驱动之i2c死锁问题