🧐 最小栈
📝 题目描述
请你设计一个支持push
、pop
、top
操作,并能在常数时间内检索到最小元素的栈。
实现MinStack
包含以下几部分内容。
MinStack()
: 初始化栈对象。void push(int val)
: 将元素val
压入栈中。void pop()
: 弹出栈顶元素。int top()
: 获取栈顶元素。int getMin()
: 获取栈中的最小元素。
📋 代码模版
java
class MinStack {
public MinStack() {
}
public void push(int val) {
}
public void pop() {
}
public int top() {
}
public int getMin() {
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
💡 提示
pop
、top
和getMin
操作总是在非空栈上调用push
、pop
、top
和getMin
最多被调用次
🚀 示例
输入
java
public static void main(String[] args) {
MinStack minStack = new MinStack();
minStack.push(2);
minStack.push(4);
minStack.push(3);
minStack.push(7);
minStack.push(1);
minStack.push(1);
minStack.push(5);
int min1 = minStack.getMin();
for (int i = 0; i < 2; i++) {
minStack.pop();
}
int min2 = minStack.getMin();
minStack.pop();
int top = minStack.top();
int min3 = minStack.getMin();
System.out.println(min1);
System.out.println(min2);
System.out.println(top);
System.out.println(min3);
}
输出
🖊️ 题解
由于栈先进后出的特点,所以对于栈中的每一个元素来说,如果其下方存在比它值还小的元素的话,那么栈中的最小元素就永远不可能为自身。例如,在以下示例中,当7、3或4存在栈中时,它们不可能是最小元素,因为它们底下还存在2这个元素。
因此,我们可以利用辅助栈向上依次记录最小值来解决这个问题,具体步骤如下。
- 创建一个辅助栈
minStack
。 - 实现
push
方法:将新的val
压入主栈mainStack
中,若minStack
大于等于val
,则将val
同时压入minStack
中,使得val
成为新的栈中最小值。此时,需要考虑minStack
本身就为空的边界情况,在这种条件下,val
也应成为新的最小值。 - 实现
pop
方法:弹出主栈mainStack
中的栈顶元素,若该元素的值与minStack
栈顶元素的值相同,则表示该元素是栈中的最小值,此时应弹出minStack
栈顶元素,这保证了minStack
中的栈顶元素始终为mainStack
中的最小值。 - 实现
getMin
方法:返回minStack
栈顶值即可。
该解法其实是基于主栈,从栈底至栈顶维护一个向上单调递减的单调栈。
java
class MinStack {
private final Deque<Integer> mainStack;
private final Deque<Integer> minStack;
public MinStack() {
mainStack = new ArrayDeque<>();
minStack = new ArrayDeque<>();
}
public void push(int val) {
mainStack.push(val);
if (minStack.isEmpty() || minStack.peek() >= val) {
minStack.push(val);
}
}
public void pop() {
Integer pop = mainStack.pop();
if (!minStack.isEmpty() && minStack.peek().equals(pop)) {
minStack.pop();
}
}
public int top() {
return mainStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
💭 复杂度分析
基于辅助栈
的解决方案的复杂度分析如下。
- 时间复杂度:
push
、pop
、top
和getMin
操作皆为。 - 空间复杂度:
。