LeetCode 第 155 题:最小栈(Min Stack)
字数 2030 2025-10-27 21:41:46
LeetCode 第 155 题:最小栈(Min Stack)
题目描述
设计一个栈,除了支持常规的入栈(push)、出栈(pop)、查看栈顶元素(top)操作外,还需要支持在 常数时间 内检索到栈中最小元素的 getMin 方法。
示例
输入操作序列:
push(-2), push(0), push(-3), getMin(), pop(), top(), getMin()
输出结果:
null, null, null, -3, null, 0, -2
解题思路
普通栈的 push、pop、top 都是 O(1) 时间,但 getMin 如果遍历栈则需要 O(n)。为了 O(1) 时间得到最小值,我们需要 额外维护一个结构,时刻记录当前栈的最小值。
方法 1:辅助栈(最小栈同步)
- 使用两个栈:
dataStack:正常保存所有元素。minStack:保存当前dataStack中对应位置的最小值。
- push(x) 操作:
- 将 x 压入
dataStack。 - 比较 x 与
minStack栈顶元素(如果minStack为空则直接压入 x),将 较小值 压入minStack。
- 将 x 压入
- pop() 操作:
- 同时弹出
dataStack和minStack的栈顶。
- 同时弹出
- top() 操作:
- 返回
dataStack的栈顶。
- 返回
- getMin() 操作:
- 返回
minStack的栈顶。
- 返回
例子演示
操作序列:push(-2), push(0), push(-3), getMin(), pop(), top(), getMin()
| 操作 | dataStack | minStack | 说明 |
|---|---|---|---|
| push(-2) | [-2] | [-2] | minStack 压入 -2 |
| push(0) | [-2,0] | [-2,-2] | 0 与 -2 比,minStack 压入 -2 |
| push(-3) | [-2,0,-3] | [-2,-2,-3] | -3 与 -2 比,minStack 压入 -3 |
| getMin() | 返回 minStack 栈顶 -3 | ||
| pop() | [-2,0] | [-2,-2] | 同时弹出 dataStack 和 minStack 栈顶 |
| top() | 返回 dataStack 栈顶 0 | ||
| getMin() | 返回 minStack 栈顶 -2 |
优点:简单直观,O(1) 时间所有操作,O(n) 额外空间。
方法 2:辅助栈(非同步,节省空间)
如果连续压入的元素都比当前最小值大,minStack 不需要每次压入新元素,可以 只在 x ≤ 当前最小值时才压入 minStack。
- push(x):
- 压入
dataStack。 - 如果
minStack为空 或 x ≤minStack栈顶,则压入minStack。
- 压入
- pop():
- 弹出
dataStack栈顶 y。 - 如果 y 等于
minStack栈顶,则弹出minStack。
- 弹出
例子演示(同上操作序列)
| 操作 | dataStack | minStack | 说明 |
|---|---|---|---|
| push(-2) | [-2] | [-2] | minStack 压入 -2 |
| push(0) | [-2,0] | [-2] | 0 > -2,minStack 不变 |
| push(-3) | [-2,0,-3] | [-2,-3] | -3 ≤ -2,minStack 压入 -3 |
| getMin() | 返回 -3 | ||
| pop() | [-2,0] | [-2] | 弹出 -3,它等于 minStack 栈顶,所以 minStack 也弹出 |
| top() | 返回 0 | ||
| getMin() | 返回 -2 |
优点:在压入元素较大时,minStack 元素较少,节省空间。
代码实现(方法 1:同步版本)
class MinStack:
def __init__(self):
self.data_stack = []
self.min_stack = []
def push(self, val: int) -> None:
self.data_stack.append(val)
if not self.min_stack:
self.min_stack.append(val)
else:
self.min_stack.append(min(val, self.min_stack[-1]))
def pop(self) -> None:
self.data_stack.pop()
self.min_stack.pop()
def top(self) -> int:
return self.data_stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
总结
- 核心思想:用辅助栈保存每个状态下的最小值。
- 同步版本简单不易出错,非同步版本可节省空间。
- 所有操作时间复杂度 O(1),空间复杂度 O(n)。