携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情 >>
一、题目 LeetCode - 155
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类:
- MinStack() 初始化堆栈对象。
- void push(int val) 将元素val推入堆栈。
- void pop() 删除堆栈顶部的元素。
- int top() 获取堆栈顶部的元素。
- int 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.
二、解题思路
本题要求自行实现一个最小栈数据结构,并支持push,pop,top操作。可以考虑对编程语言提供的原生栈实现进行包装、改造,使其可以在常数时间内检索到最小元素。具体做法如下:
- 首先创建一个栈结构用于存储push的数据,命名为stack;
- 再另外使用一个栈,用于存储当前push入栈的最小元素,命名为minStack,要注意这个栈的入栈规则为:
- 若当前push入stack栈的元素小于minStack栈的栈顶元素,则将当前元素push入minStack;
- 若当前push入stack栈的元素大于或等于minStack栈的栈顶元素,则将minStack栈的栈顶元素再次push入minStack;
- 当执行pop命令时,不仅需要对stack弾栈,也要对minStack弾栈,这样就可以保证minStack的栈顶元素是当前入栈元素中最小的元素,并且可以达到常数时间检索。
代码
class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack() {
this.stack = new Stack<>();
this.minStack = new Stack<>();
minStack.push(Integer.MAX_VALUE);
}
public void push(int val) {
stack.push(val);
if (val < minStack.peek()){
minStack.push(val);
}else {
minStack.push(minStack.peek());
}
}
public void pop() {
if (!stack.isEmpty()){
stack.pop();
minStack.pop();
}
}
public int top() {
if (!stack.isEmpty()){
return stack.peek();
}
return 0;
}
public int getMin() {
return minStack.peek();
}
}
五、总结
本题使用双栈结构使其检索的时间复杂度达到O(1),并且入栈和出栈的时间复杂度均为O(1)。空间复杂度为O(n)。