2021/5/16 刷题笔记最小栈与辅助栈思想
Posted 黑黑白白君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021/5/16 刷题笔记最小栈与辅助栈思想相关的知识,希望对你有一定的参考价值。
最小栈
【题目】
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() ——检索栈中的最小元素。
示例:
输入: [“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.提示:pop、top 和 getMin 操作总是在 非空栈 上调用。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/min-stack
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
【我的方法】
- 考虑到要在常数时间内检索到最小元素,意味不能在getMin进行计算,而是在push和pop里面计算得到最小元素。
- 所以决定以空间换时间,创建另外一个list来存储栈底到当前位置的最小值。
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.stack = []
self.minN = [] #栈底到当前位置最小值
def push(self, val: int) -> None:
if not self.minN:
self.minN.append(val)
elif self.minN[-1]>val:
self.minN.append(val)
else:
self.minN.append(self.minN[-1])
self.stack.append(val)
def pop(self) -> None:
self.stack = self.stack[:-1]
self.minN = self.minN[:-1]
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.minN[-1]
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
执行结果:
- 执行用时:60 ms, 在所有 Python3 提交中击败了92.38%的用户
- 内存消耗:17.9 MB, 在所有 Python3 提交中击败了77.53%的用户
辅助栈思想
以空间换时间的情况下,使用辅助栈是常见的做法。在代码实现的时候有两种方式。
1、辅助栈和数据栈同步
- 特点:编码简单,不用考虑一些边界情况。
- 缺点:辅助栈可能会存一些“不必要”的元素。
参考代码:
class MinStack:
# 辅助栈和数据栈同步
# 思路简单不容易出错
def __init__(self):
# 数据栈
self.data = []
# 辅助栈
self.helper = []
def push(self, x):
self.data.append(x)
if len(self.helper) == 0 or x <= self.helper[-1]:
self.helper.append(x)
else:
self.helper.append(self.helper[-1])
def pop(self):
if self.data:
self.helper.pop()
return self.data.pop()
def top(self):
if self.data:
return self.data[-1]
def getMin(self):
if self.helper:
return self.helper[-1]
复杂度分析:
2、辅助栈和数据栈不同步
- 特点:在“辅助栈和数据栈同步”思想的基础上做一些“优化”,但是在编码上就要注意一些边界条件。
- 辅助栈为空的时候,必须放入新进来的数。
- 新来的数小于或者等于辅助栈栈顶元素的时候,才放入,特别注意这里“等于”要考虑进去,因为出栈的时候,连续的、相等的并且是最小值的元素要同步出栈。
- 出栈的时候,辅助栈的栈顶元素等于数据栈的栈顶元素,才出栈。
即出栈时,最小值出栈才同步;
入栈时,最小值入栈才同步。
虽然减少了一些空间,但是在“出栈”、“入栈”的时候还要做判断,也有性能上的消耗。
参考代码:
# 辅助栈和数据栈不同步
# 关键 1:辅助栈的元素空的时候,必须放入新进来的数
# 关键 2:新来的数小于或者等于辅助栈栈顶元素的时候,才放入(特别注意这里等于要考虑进去)
# 关键 3:出栈的时候,辅助栈的栈顶元素等于数据栈的栈顶元素,才出栈,即"出栈保持同步"就可以了
def __init__(self):
# 数据栈
self.data = []
# 辅助栈
self.helper = []
def push(self, x):
self.data.append(x)
# 关键 1 和关键 2
if len(self.helper) == 0 or x <= self.helper[-1]:
self.helper.append(x)
def pop(self):
# 关键 3:【注意】不论怎么样,数据栈都要 pop 出元素
top = self.data.pop()
if self.helper and top == self.helper[-1]:
self.helper.pop()
return top
def top(self):
if self.data:
return self.data[-1]
def getMin(self):
if self.helper:
return self.helper[-1]
复杂度分析:
【部分内容参考自】
- 使用辅助栈(同步和不同步,Python 代码、Java 代码):https://leetcode-cn.com/problems/min-stack/solution/shi-yong-fu-zhu-zhan-tong-bu-he-bu-tong-bu-python-/
以上是关于2021/5/16 刷题笔记最小栈与辅助栈思想的主要内容,如果未能解决你的问题,请参考以下文章