问题描述
设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) -- 将元素 x 推入栈中。
- pop() -- 删除栈顶的元素。
- top() -- 获取栈顶元素。
- getMin() -- 检索栈中的最小元素。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
问题思路
这道题最难的地方就在于getMin()函数的求法。
一开始我想的是利用一个辅助变量来存储最小的数。当进栈时,判断入栈变量与辅助变量的大小关系,然后改变辅助变量的值;当出栈时,如果出栈变量是最小的值时,则遍历栈,找到最小元素赋值给辅助变量,但是很显然,这种做法在使用pop()方法时的时间复杂度是O(n),不是很可取。
之后我又查阅了其他同学的代码,发现他们利用了一个辅助栈,采用了“空间换时间”的策略,用来达到O(1)的时间复杂度。
具体做法如下:
- 定义双栈,一个用来存储数据,另外一个用来存储比第一个数以及比它更小数据。
- 当入栈时,首先检查辅助栈是否为空和辅助栈中的最后一个元素是否比入栈元素大,如果比它大,则把入栈元素放入双栈,否则只放入数据栈。
- 当出栈时,检查出栈元素是否为最小元素,如果是,则出双栈,否则只需要数据栈元素出栈即可。
具体代码
代码1(暴力解法)
class MinStack(object):
stack = []
min = None
def __init__(self):
"""
initialize your data structure here.
"""
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.stack.append(x)
if self.min == None or x < self.min:
self.min = x
def pop(self):
"""
:rtype: None
"""
item = self.stack.pop()
if item == self.min:
localMin = None
for i in self.stack:
if localMin == None or i < localMin:
localMin = i
self.min = localMin
return item
def top(self):
"""
:rtype: int
"""
return self.stack[-1]
def getMin(self):
"""
:rtype: int
"""
return self.min
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
代码2(辅助栈)
class MinStack(object):
stack1 = []
stack2 = []
min = None
def __init__(self):
"""
initialize your data structure here.
"""
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.stack1.append(x)
if not self.stack2 or x <= self.stack2[-1]:
self.stack2.append(x)
def pop(self):
"""
:rtype: None
"""
if self.stack1:
item = self.stack1.pop()
if item == self.stack2[-1]:
self.stack2.pop()
return item
return False
def top(self):
"""
:rtype: int
"""
if self.stack1:
return self.stack1[-1]
def getMin(self):
"""
:rtype: int
"""
if self.stack2:
return self.stack2[-1]
网友评论