Leetcode【栈】| 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.
提示:pop、top 和 getMin 操作总是在 非空栈 上调用。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-stack
解题
题目分析
乍一看这题输入输出没看懂,其实很简单,就是设计一个栈类叫最小栈,和普通栈(java自带的stack类)的区别就在于多了一个可以返回当前栈内最小值的getMin()方法。Stack栈类的其他方法照常可以使用。我们的主要问题就是求解怎么在常数时间检索出当前栈内所有元素的最小值。
对于一个最小栈minStack来说,题目中要求的四个方法:
- 入栈方法:push(x),和Stack类的入栈方法一样,可以直接用stack.push(x)实现
- 出栈方法:pop() ,和Stack类的出栈方法一样,可以直接用stack.pop()实现。
- 获取栈顶元素方法:top(),Stack类同样有类似的方法peek(),peek()和pop()的去区别在于两者都能返回栈顶元素的值,但是pop()会同时删除栈顶元素,peek()不删。
- 检索栈中的最小元素方法:getMin(),只有此方法原本的Stack类中没有,我们需要设计实现。
两个栈实现(创建一个辅助栈存储最小值)
我们可以在minStack栈内用两个栈来实现存储当前栈内的最小值。
一个栈stack为普通的栈,依次存储我们压入栈的值。
另一个栈stackmin和上个栈同等大小,同步上一个栈的所有操作,一一对应,只不过存储的是栈stack中对应元素作为栈顶元素时的当前stack栈内元素的最小值,这个栈作为一个辅助栈。
如何存储?因为两个栈同步,我们维护一个当前最小值的变量,所以每当stack栈中加入一个元素,与之前维护的最小值变量相比,如果比之前的小就更新最小值变量,如果没之前那个小就维护之前那个值将其压入stackmin栈中。
这样我们在minStack类中的getMin()方法中只需将当前的minStack栈中的栈顶元素弹出即可。比如示例中输入的意思其实是,先构造一个minStack,然后依次压入push值-2、0、-3,然后获取当前栈内的最小值。当前的两个栈内元素如下图解:(所以当前栈内元素最小值是-3)
然后我们弹出一个栈顶元素的话,两个栈都同步弹出栈顶元素。两个栈更新如下图:(那么此时栈内元素的最小值就变为-2了)
class MinStack {
public Stack<Integer> stack;
public Stack<Integer> stackmin;
/** initialize your data structure here. */
public MinStack() {
stack = new Stack<>();
stackmin = new Stack<>();
}