LeetCode 热题 100 155. 最小栈
LeetCode 热题 100 | 155. 最小栈
大家好!今天我们来解决一道经典的算法题——最小栈。这道题要求我们设计一个支持 push
、pop
、top
操作,并能在常数时间内检索到最小元素的栈。下面我将详细讲解解题思路,并附上Python代码实现。
一、问题描述
设计一个支持以下操作的栈:
MinStack()
:初始化栈对象。void push(int val)
:将元素val
推入栈。void pop()
:删除栈顶部的元素。int top()
:获取栈顶部的元素。int getMin()
:获取栈中的最小元素。
要求所有操作的时间复杂度为 O(1)。
示例:
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]输出:
[null,null,null,null,-3,null,0,-2]解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
二、解题思路
核心思想
为了在常数时间内获取栈中的最小元素,我们需要在每次操作时维护当前栈的最小值。具体方法如下:
- 辅助栈:
- 使用两个栈:一个主栈
stack
用于存储所有元素,一个辅助栈minStack
用于存储当前栈的最小值。 - 每次
push
时,将元素压入主栈,并将当前最小值压入辅助栈。 - 每次
pop
时,同时从主栈和辅助栈中弹出元素。 getMin
操作直接返回辅助栈的栈顶元素。
- 使用两个栈:一个主栈
代码实现
class MinStack:def __init__(self):# 初始化主栈和辅助栈self.stack = []self.minStack = []def push(self, val: int) -> None:# 将元素压入主栈self.stack.append(val)# 将当前最小值压入辅助栈if not self.minStack or val < self.minStack[-1]:self.minStack.append(val)else:self.minStack.append(self.minStack[-1])def pop(self) -> None:# 从主栈和辅助栈中弹出元素self.stack.pop()self.minStack.pop()def top(self) -> int:# 返回主栈的栈顶元素return self.stack[-1]def getMin(self) -> int:# 返回辅助栈的栈顶元素,即当前栈的最小值return self.minStack[-1]
代码解析
-
初始化:
- 在
__init__
方法中,初始化两个栈:stack
和minStack
。
- 在
-
push
操作:- 将元素压入主栈
stack
。 - 如果辅助栈为空或新元素小于辅助栈的栈顶元素,则将新元素压入辅助栈;否则,将辅助栈的栈顶元素再次压入辅助栈。
- 将元素压入主栈
-
pop
操作:- 同时从主栈和辅助栈中弹出元素。
-
top
操作:- 返回主栈的栈顶元素。
-
getMin
操作:- 返回辅助栈的栈顶元素,即当前栈的最小值。
复杂度分析
- 时间复杂度:所有操作的时间复杂度均为 O(1)。
- 空间复杂度:O(n),其中 n 是栈中元素的数量。辅助栈
minStack
的大小与主栈相同。
示例运行
示例1
# 创建 MinStack 对象
minStack = MinStack()
# 执行操作
minStack.push(-2)
minStack.push(0)
minStack.push(-3)
print(minStack.getMin()) # 输出 -3
minStack.pop()
print(minStack.top()) # 输出 0
print(minStack.getMin()) # 输出 -2
输出:
-3
0
-2
总结
通过使用辅助栈,我们可以在常数时间内实现 push
、pop
、top
和 getMin
操作。这种方法不仅简单高效,而且易于理解和实现。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!
关注我,获取更多算法题解和编程技巧!