题目链接:155. Min Stack 最小栈
解题思路:
使用两个栈来实现本题要求,一个栈用于保存所有元素,这个栈与普通栈没有区别,记为stackData
;另一个栈用于保存每一步的最小值,记为stackMin
。
push(x)
操作 - 将元素 x 推入栈中。
当前元素记为newNum
,压入stackData
。然后判断stackMin
是否为空:- 若
stackMin
为空,也入栈; - 若
stackMin
不为空,则将newNum
与stackMin
栈顶元素比较。
若newNum <= stackMin栈顶元素
,则newNum
压入stackMin
;
否则stackMin
不执行操作。
- 若
pop()
操作 - 删除栈顶的元素。
先将stackData
进行出栈,并保存其栈顶元素,记为stackDataTop
。
由设计思路可知,stackMin
的栈顶一定小于等于stackData
的栈顶,且stackMin
从栈底到栈顶依次减小,stackMin
栈顶元素也是全部数据的最小值。
若stackDataTop == stackMin栈顶
,stackMin
也需进行出栈操作。注意:这一步是必须进行判断的。这是因为:若最后压入栈的元素是最小的,若只对stackData
进行出栈而不对stackMin
进行出栈,进行getMin()
操作时,从stackMin
得到的最小值会是错误的。top()
操作 - 获取栈顶元素。
直接对stackData
进行peek()
操作即可。getMin()
操作 - 检索栈中的最小元素。
stackMin
的栈顶元素即是最小元素,对stackMin
进行peek()
操作即可。
代码实现:
class MinStack {
// 用于存储所有数据
private Stack<Integer> stackData;
// 用于存储每一步的最小值
private Stack<Integer> stackMin;
/** initialize your data structure here. */
public MinStack() {
this.stackData = new Stack<Integer>();
this.stackMin = new Stack<Integer>();
}
public void push(int x) {
// 若stackMin为空,也一并入栈
if (this.stackMin.isEmpty()) {
this.stackMin.push(x);
}
// 若当前元素小于stackMin栈顶元素,stackMin入栈
else if (x <= this.stackMin.peek()) {
this.stackMin.push(x);
}
this.stackData.push(x);
}
public void pop() {
if (this.stackData.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
int stackDataTop = this.stackData.pop();
// 如果stackData栈顶元素与stackMin栈顶元素相等,stackMin也要进行出栈
if (stackDataTop == this.stackMin.peek()) {
this.stackMin.pop();
}
}
public int top() {
return this.stackData.peek();
}
public int getMin() {
return this.stackMin.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
提交结果:
执行用时:7ms;内存消耗:40MB;战胜91.71%。
参考:左程云《程序员代码面试指南:IT名企算法与数据结构题目最优解》