题目链接:https://leetcode.cn/problems/min-stack/description/?envType=problem-list-v2&envId=2cktkvj

1、思路分析
普通栈的 push、pop、top 都是 O(1),但 getMin 需要遍历整个栈才能找到最小值,那是 O(n)。
关键技巧 :用辅助栈同步记录每个状态下的最小值。
维护两个栈:
主栈 stack:正常存储所有元素
辅助栈 min_stack:存储每个位置对应的当前最小值
规则:
push(value):
主栈正常压入 value
辅助栈压入 min(value, 当前最小值)
pop():
两个栈同时弹出
top():
返回主栈栈顶
getMin():
返回辅助栈栈顶(就是当前最小值)
2、图解示例
执行:push(-2), push(0), push(-3), getMin(), pop(), top(), getMin()
步骤 1:push(-2)
主栈: -2
辅助栈: -2 ← 当前最小值 = -2
步骤 2:push(0)
主栈: -2, 0
辅助栈: -2, -2 ← min(0, -2) = -2
步骤 3:push(-3)
主栈: -2, 0, -3
辅助栈: -2, -2, -3 ← min(-3, -2) = -3
此时 getMin() 返回辅助栈栈顶 = -3
3、代码实现
python
class MinStack:
def __init__(self):
# 主栈:存储所有元素
self.stack = []
# 辅助栈:存储每个位置对应的最小值
self.min_stack = []
def push(self, value: int) -> None:
self.stack.append(value)
# 如果辅助栈为空,或者当前值比辅助栈顶(当前最小值)还小
if not self.min_stack or value <= self.min_stack[-1]:
self.min_stack.append(value)
else:
# 否则,重复压入当前最小值
self.min_stack.append(self.min_stack[-1])
def pop(self) -> None:
# 两个栈同时弹出
self.stack.pop()
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
优化版本(节省空间)
上面的实现中,辅助栈可能存储很多重复的最小值。可以优化:只在最小值变化时才压入辅助栈。
python
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = [] # 只存储最小值(不重复)
def push(self, value: int) -> None:
self.stack.append(value)
# 只有 value <= 当前最小值时,才压入辅助栈
if not self.min_stack or value <= self.min_stack[-1]:
self.min_stack.append(value)
def pop(self) -> None:
popped = self.stack.pop()
# 如果弹出的元素正好是当前最小值,辅助栈也要弹出
if popped == self.min_stack[-1]:
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
对比两种实现:

复杂度分析
- 时间复杂度:所有操作都是 O(1)
- 空间复杂度:O(n),n 是栈中元素个数