题目:

155. 最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

示例:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.

方法一:使用两个栈

思路:

  1. 定义两个栈stack和minStack,stack用来保存正常入栈出战栈的值,最小栈minStack的栈顶用来存当前所有元素的最小值。
  2. 存最小值的具体流程如下:
    ① 将第一个元素入栈。
    ② 新加入的元素如果大于栈顶元素,那么新加入的元素就不处理。
    ③ 新加入的元素如果小于等于栈顶元素,那么就将新元素入栈。
    ④ 出栈元素不等于栈顶元素,不操作。
    ⑤ 出栈元素等于栈顶元素,那么就将栈顶元素出栈。
入栈 3 
| | | |
| | | |
|_3_| |_3_|
stack minStack

入栈 5 , 5 大于 minStack 栈顶,不处理
| | | |
| 5 | | |
|_3_| |_3_|
stack minStack

入栈 2 ,此时右边的 minStack 栈顶就保存了当前最小值 2
| 2 | | |
| 5 | | 2 |
|_3_| |_3_|
stack minStack

出栈 2,此时右边的 minStack 栈顶就保存了当前最小值 3
| | | |
| 5 | | |
|_3_| |_3_|
stack minStack

出栈 5,右边 minStack 不处理
| | | |
| | | |
|_3_| |_3_|
stack minStack

出栈 3
| | | |
| | | |
|_ _| |_ _|
stack minStack
class MinStack {
Stack<Integer> stack;
Stack<Integer> minStack;

public MinStack() {
stack = new Stack();
minStack = new Stack();
}

public void push(int val) {
stack.push(val);
if(!minStack.isEmpty()){
if(val <= minStack.peek()){
minStack.push(val);
}
}
else {
minStack.push(val);
}
}

public void pop() {
if(stack.pop().equals(minStack.peek())){
minStack.pop();
}
}

public int top() {
return stack.peek();
}

public int getMin() {
return minStack.peek();
}
}

方法二:使用一个栈

思路:
我们可以使用一个变量存储最小值。但是这个会遇到一个问题,比如:我们一开始分别将3入栈,此时最小值min为3, 再将5入栈,此时最小值min=3,这时我们再将2入栈,如果只用一个变量就会遇到一个问题:此时如果把min更新为2,那么之前的最小值3就丢失了。

入栈 3 
| | min = 3
| |
|_3_|
stack

入栈 5
| | min = 3
| 5 |
|_3_|
stack

入栈 2
| 2 | min = 2?
| 5 |
|_3_|
stack

怎么把3保存起来呢? 解决办法:把它在2之前压入栈中即可。

入栈 2 ,同时将之前的 min 值 3 入栈,再把 2 入栈,同时更新 min = 2
| 2 | min = 2
| 3 |
| 5 |
|_3_|
stack

入栈 6
| 6 | min = 2
| 2 |
| 3 |
| 5 |
|_3_|
stack

出栈 6
| 2 | min = 2
| 3 |
| 5 |
|_3_|
stack

出栈 2
| 2 | min = 2
| 3 |
| 5 |
|_3_|
stack

上面的最后一个状态,当出栈元素是最小元素我们该如何处理呢?
我们只需要把2出栈,然后再出栈一次,把2赋值给min即可。

出栈 2     
| | min = 3
| 5 |
|_3_|
stack

总结:
当有更小的值来的时候,我们只需要把之前的最小值入栈,当前更小的值再入栈即可。当这个最小值要出栈的时候,下一个值便是之前的最小值了。

class MinStack {
int min = Integer.MAX_VALUE;
Stack<Integer> stack = new Stack<Integer>();
public void push(int x) {
//当前值更小
if(x <= min){
//将之前的最小值保存
stack.push(min);
//更新最小值
min=x;
}
stack.push(x);
}

public void pop() {
//如果弹出的值是最小值,那么将下一个元素更新为最小值
if(stack.pop() == min) {
min=stack.pop();
}
}

public int top() {
return stack.peek();
}

public int getMin() {
return min;
}
}

方法三:使用一个栈的另一种思路