Min Stack 115
2015-01-1610:32:50
题目描述:
设计一个栈,支持 pop(), push(int x), top(), getMin()/*返回栈中的最小值*/
并且要求这几个操作都是常数时间的复杂度 O(1)
题目分析:
要返回最小值,首先想到的是push一个元素之后对栈排序,但是这违背了栈的后进先出原则,并且复杂度是O(n)
其次可以考虑用一个元素记录push中出现的最小值。但是当执行pop这个最小值出栈之后,次小值是什么呢?
看来我们不止要记录最小值一个元素,可以考虑用另外一个栈记录当前位置的最小值。
每次添加元素时,将当前最小元素与要添加的元素比较取其中的小值,添加到最小值栈的栈顶
步骤 | 操作 | 数据栈 | 最小值栈 | 最小值 |
1 | push 7 | 7 | 7 | 7 |
2 | push 3 | 7,3 | 7,3 | 3 |
3 | push 5 | 7,3,5 | 7,3,3 | 3 |
4 | push 1 | 7,3,5,1 | 7,3,3,1 | 1 |
5 | push 2 | 7,3,5,1,2 | 7,3,3,1,1 | 1 |
6 | push 1 | 7,3,5,1,2,1 | 7,3,3,1,1,1 | 1 |
7 | pop | 7,3,5,1,2 | 7,3,3,1,1 | 1 |
8 | pop | 7,3,5,1 | 7,3,3,1 | 1 |
9 | pop | 7,3,5 | 7,3,3 | 3 |
优化:
在最小值栈中我们会看到有相邻的重复元素,比如上面的3,3 和 1,1,1
实际上我们只要记录重复值的一个就可以了,
比如第三步中添加 5 ,5大于当前的最小值3,这个时候最小值栈可以不添加元素,保持不变;
当元素出栈时,如果出栈的元素时当前最小值,那么最小值栈也退出当天最小值
不过当添加元素等于当前的最小值时,该不该添加,
假如不添加,对于上面的例子到第6步最小值栈中的元素应该是 7,3,1
当执行第8步时,因为出栈元素1是当前最小值,最小值栈当前最小值也要出栈,这样最小值栈中元素是 7,3
但是我们发现其实还有最小值1
因此当添加元素等于当前最小值时,要在最小值栈中添加一个副本
对于上面例子中第6步最小值栈中元素应该是 7,3,1,1
代码:
1 stack<int> stk; 2 stack<int> minstk; 3 4 void push(int x) { 5 stk.push(x); 6 if(minstk.empty() || x<=minstk.top()) 7 minstk.push(x); 8 } 9 10 void pop() { 11 if(stk.empty())return ; 12 int x=stk.top(); 13 stk.pop(); 14 if(x==minstk.top()) 15 minstk.pop(); 16 } 17 18 int top() { 19 if(stk.empty())return 0; 20 return stk.top(); 21 }