topic
Design a stack that supports push, pop, top operations, and can retrieve the smallest element in constant time.
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
ideas
Auxiliary stack
The title requires that the smallest element can be retrieved in Changshu time. Constant time is O(1) time complexity, so you cannot use for loop to traverse and retrieve, and the time complexity of for loop is O(n)
The idea is to maintain another auxiliary stack minStack, so that the top of the auxiliary stack always saves the smallest element in the current stack
class MinStack:
def __init__(self):
# 普通栈
self.stack = []
# 辅助栈,初始化给一个无穷大
self.min_stack = [math.inf]
def push(self, val: int) -> None:
# 普通栈正常push
self.stack.append(val)
# 辅助栈只push小于等于栈顶的
self.min_stack.append(min(val,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]
Do not use auxiliary stack
The problem can also be solved with just one stack.
The method of assisting the stack is to add a stack to maintain the minimum value.
With only one stack, you only need to add a new variable to hold the minimum value. When the data is pushed into and out of the stack, through some methods, the change of the minimum value is recorded in the data stack.
Method one:
When an element is pushed onto the stack, if the pushed value is smaller than the current minimum value, the variable that holds the minimum value will be updated. The previous minimum value is also pushed into the stack to save, and then a new element is pushed onto the stack.
入栈 3
| | min = 3
| |
|_3_|
stack
入栈 5
| | min = 3
| 5 |
|_3_|
stack
入栈 2
| 2 | min = 2?
| 5 |
|_3_|
stack
入栈2时,栈中最小值变成了2,如果直接将min跟新成2,那之前的最小值3就会丢失
为了保存之前的最小值3,在入栈2时,先将之前最小值3入栈保存在栈中,然后在入栈2,更新min
也就是,当新入栈的值,比之前的最小值还小,就将旧的最小值先保存到栈中,在入栈新的值,并且更新最小值为新入栈的值
| 2 | min = 2
| 3 |
| 5 |
|_3_|
stack
入栈 6
| 6 | min = 2
| 2 |
| 3 |
| 5 |
|_3_|
stack
出栈 6
| 2 | min = 2
| 3 |
| 5 |
|_3_|
stack
出栈 2
| 2 | min = 2
| 3 |
| 5 |
|_3_|
stack
出栈时,当前top元素,和当前min值相同时,说明当前top元素,在入栈时是更新了最小值的元素,也就是说它的下一个元素,是之前旧的min值
所以,出栈2,出栈3,同时更新min=3
作者:windliang
链接:https://leetcode-cn.com/problems/min-stack/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-38/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
python code
class MinStack:
def __init__(self):
self.stack = []
self.min = -1
def push(self, val: int) -> None:
if not self.stack:
self.stack.append(val)
self.min = val
else:
# 这里必须用<=,必须也要包含等于
# 比如依次push 0,1,0,push第3个0时,它等于最小值0,
# 也需要先插入一个最小值到栈中
# 如果不这么做,pop 0的时候,0等于最小值,会认为前面的1是之前的最小值
# 但1只是正常push入栈的元素
if val <= self.min:
self.stack.append(self.min)
self.min = val
self.stack.append(val)
def pop(self) -> None:
top = self.stack.pop()
# 不要忘记pop后空栈的边界情况 self.stack
if self.stack and top==self.min:
self.min=self.stack.pop()
return top
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min
Method two:
The principle is the same as above, but the operation is slightly different.
When pushing, the value is not directly stored, but the difference between the stored value and the current minimum value.
When pushing:
- Push value > minimum value, push(Push value - minimum value), the minimum value remains unchanged
- Push value < minimum value, push(push value - old minimum value), new minimum value becomes push value
When pop:
- Stack top value > 0, push value = stack top value + minimum value, minimum value remains unchanged
- stack top value < 0, push value = minimum value, previous minimum value = push value - stack top value = minimum value - stack top value
入栈 3,存入 3 - 3 = 0
| | min = 3
| |
|_0_|
stack
入栈 5,存入 5 - 3 = 2
| | min = 3
| 2 |
|_0_|
stack
入栈 2,因为出现了更小的数,所以我们会存入一个负数,这里很关键
也就是存入 2 - 3 = -1, 并且更新 min = 2
对于之前的 min 值 3, 我们只需要用更新后的 min - 栈顶元素 -1 就可以得到
| -1| min = 2
| 5 |
|_3_|
stack
入栈 6,存入 6 - 2 = 4
| 4 | min = 2
| -1|
| 5 |
|_3_|
stack
出栈,返回的值就是栈顶元素 4 加上 min,就是 6
| | min = 2
| -1|
| 5 |
|_3_|
stack
出栈,此时栈顶元素是负数,说明之前对 min 值进行了更新。
入栈元素 - min = 栈顶元素,入栈元素其实就是当前的 min 值 2
所以更新前的 min 就等于入栈元素 2 - 栈顶元素(-1) = 3
| | min = 3
| 5 |
|_3_|
stack
作者:windliang
链接:https://leetcode-cn.com/problems/min-stack/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-38/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
python code
class MinStack:
def __init__(self):
self.stack = []
self.min = -1
def push(self, val: int) -> None:
if not self.stack :
self.min = val
diff = val - self.min
self.stack.append(diff)
if diff < 0:
self.min = val
def pop(self) -> None:
diff = self.stack.pop()
if diff < 0:
top = self.min
old_min = top - diff
self.min = old_min
else:
top = self.min + diff
return top
def top(self) -> int:
diff = self.stack[-1]
top = (diff + self.min) if diff>0 else self.min
return top
def getMin(self) -> int:
return self.min
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。