文章目录
一、题目描述
设计一个支持 push、pop、top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack()初始化栈对象。void push(int val)将元素 val 压入栈中。void pop()删除栈顶元素。int top()获取栈顶元素。int getMin()检索栈中的最小元素。
所有操作的时间复杂度均需为 O(1)。
二、思维导图梳理
三、解法原理剖析
方法一:使用辅助最小栈
为了在 O(1) 时间内得到最小值,我们可以使用两个栈:
- 数据栈(dataStack):正常存储入栈的数据。
- 最小值栈(minStack):同步记录对应位置的最小值。
思路解析
| 操作 | dataStack | minStack |
|---|---|---|
| push(5) | [5] | [5] |
| push(3) | [5, 3] | [5, 3](3是当前最小值) |
| push(7) | [5, 3, 7] | [5, 3, 3](3仍是最小) |
| pop() | [5, 3] | [5, 3] |
| getMin() | 返回 minStack 栈顶元素 3 |
每次压入新值时,minStack 栈顶保存的是当前所有元素的最小值。
方法二:仅使用一个栈,记录差值
可以只用一个栈,通过记录当前值与最小值的差来避免使用双栈。
- 记录最小值
min - 压栈时存储差值:
val - min - 当压入比当前最小值更小的元素时,特别更新最小值。
这种方式比较巧妙,但对负差值的计算要格外注意,因此一般更推荐双栈法。
方法三:同栈存储元组 (val, minVal)
每个栈元素同时记录当前值和当前最小值,此时只需一个栈,每次压入:
栈顶元素 = [当前值, 当前最小值]
取最小值时读取栈顶元素的第二个字段即可。
四、操作流程图
以下是“辅助最小栈”解法的流程示意:
五、复杂度分析
| 操作 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| push | O(1) | O(n) |
| pop | O(1) | O(n) |
| top | O(1) | O(n) |
| getMin | O(1) | O(n) |
时间复杂度始终保持常数级,空间由于维护辅助栈为线性级。
六、Java 解法代码
下面是实现完整的双栈版本代码:
class MinStack {
private Stack<Integer> dataStack;
private Stack<Integer> minStack;
public MinStack() {
dataStack = new Stack<>();
minStack = new Stack<>();
}
public void push(int val) {
dataStack.push(val);
if (minStack.isEmpty() || val <= minStack.peek()) {
minStack.push(val);
} else {
minStack.push(minStack.peek());
}
}
public void pop() {
dataStack.pop();
minStack.pop();
}
public int top() {
return dataStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
七、总结
| 特性 | 描述 |
|---|---|
| 设计思路 | 用辅助栈同步记录最小值 |
| 优点 | 操作简单,逻辑清晰,性能稳定 |
| 缺点 | 空间使用略多 |
| 时间复杂度 | O(1) |
| 空间复杂度 | O(n) |
——155. 最小栈&spm=1001.2101.3001.5002&articleId=157843699&d=1&t=3&u=be9f1dc53c494d71bbfc300b969aab8c)
540

被折叠的 条评论
为什么被折叠?



