文章目录
-
- 一、题目描述
- 二、思维导图梳理
- 三、解法原理剖析
-
- 方法一:使用辅助最小栈
- 方法二:仅使用一个栈,记录差值
- [方法三:同栈存储元组 `(val, minVal)`](#方法三:同栈存储元组
(val, minVal))
- 四、操作流程图
- 五、复杂度分析
- [六、Java 解法代码](#六、Java 解法代码)
- 七、总结
一、题目描述
设计一个支持 push、pop、top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack()初始化栈对象。void push(int val)将元素 val 压入栈中。void pop()删除栈顶元素。int top()获取栈顶元素。int getMin()检索栈中的最小元素。
所有操作的时间复杂度均需为 O(1)。
二、思维导图梳理
Min Stack
设计要求
push(val)
pop()
top()
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)
每个栈元素同时记录当前值和当前最小值,此时只需一个栈,每次压入:
text
栈顶元素 = [当前值, 当前最小值]
取最小值时读取栈顶元素的第二个字段即可。
四、操作流程图
以下是"辅助最小栈"解法的流程示意:
是
否
是
否
开始
push(val)
minStack 是否为空?
minStack.push(val)
val < minStack.top()?
minStack.push(val)
minStack.push(minStack.top())
dataStack.push(val)
结束
五、复杂度分析
| 操作 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| push | O(1) | O(n) |
| pop | O(1) | O(n) |
| top | O(1) | O(n) |
| getMin | O(1) | O(n) |
时间复杂度始终保持常数级,空间由于维护辅助栈为线性级。
六、Java 解法代码
下面是实现完整的双栈版本代码:
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) |