描述
实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值。
你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成。
如果堆栈中没有数字则不能进行min方法的调用
您在真实的面试中是否遇到过这个题?
是
样例
如下操作:push(1),pop(),push(2),push(3),min(), push(1),min() 返回 1,2,1
实现代码:
思路:
定义两个栈, 一个用来存放数值,叫做数据栈stackData, 一个用来记录最小值,叫做最小值栈stackMin。当向数据栈中存入元素时,与最小值栈的栈顶元素比较,如果小于等于栈顶元素,则压入最小值栈中;从数据栈中弹出元素时,也要和最小值栈的栈顶元素比较,如果相等, 则最小值栈的栈顶元素弹出。操作过程中都要对栈进行判空处理。
在进行最小值栈的处理时,有两种方案,一种是当压入数据小于等于栈顶元素时,压入最小值栈中,否则不做操作;第二种方案是,当压入数据小于等于栈顶元素时,压入最小值栈中,当压入数据大于栈顶元素中,将栈顶元素重复压入最小值栈中。
方案一和方案二的共同点是所有的操作的时间复杂度都为O(1),空间复杂度都为O(n)。区别是:方案一中stackMin压入时稍微节省空间,但是弹出操作稍费时间;方案二中stackMin压入是稍费空间,但是弹出操作稍微节省时间。
方案一代码:
class MinStack: def __init__(self): # do intialization if necessary self.stackData = [] # 存放入栈的值 self.stackMin = [] # 存放最小值 """ @param: number: An integer @return: nothing """ def push(self, number): # write your code here if not len(self.stackMin): # 最小值栈里为空, 直接放入 self.stackMin.append(number) elif number <= self.min(): # 如果最小值栈里有值, 则进行比较, 如果小于等于,则放入栈中 self.stackMin.append(number) self.stackData.append(number) # 数据直接放入数据栈中 """ @return: An integer """ def pop(self): # write your code here if not len(self.stackData): # 先对数据栈进行判空 raise ValueError('your stack is empty!') val = self.stackData.pop() if val == self.min(): # 如果数据栈里的值等于最小值栈, 则弹出最小值, 相当于更新了数据栈中的最小值 self.stackMin.pop() return val """ @return: An integer """ def min(self): # write your code here if not len(self.stackMin): raise ValueError('your stack is empty!') return self.stackMin[-1] # 返回当前最小值, 相当于执行peek操作
方案二代码:
class MinStack:
def __init__(self):
# do intialization if necessary
self.stackData = [] # 存放入栈的值
self.stackMin = [] # 存放最小值
def __init__(self):
# do intialization if necessary
self.stackData = [] # 存放入栈的值
self.stackMin = [] # 存放最小值
"""
@param: number: An integer
@return: nothing
"""
def push(self, number):
# write your code here
if not len(self.stackMin): # 最小值栈里为空, 直接放入
self.stackMin.append(number)
elif number <= self.min(): # 如果最小值栈里有值, 则进行比较, 如果小于等于,则放入栈中
self.stackMin.append(number)
else:
self.stackMin.append(self.min()) # 如果number大于最小值, 则重复压入当前最小值
self.stackData.append(number) # 数据直接放入数据栈中
"""
@return: An integer
"""
def pop(self):
# write your code here
if not len(self.stackData): # 先对数据栈进行判空
raise ValueError('your stack is empty!')
self.stackMin.pop()
return self.stackData.pop()
@param: number: An integer
@return: nothing
"""
def push(self, number):
# write your code here
if not len(self.stackMin): # 最小值栈里为空, 直接放入
self.stackMin.append(number)
elif number <= self.min(): # 如果最小值栈里有值, 则进行比较, 如果小于等于,则放入栈中
self.stackMin.append(number)
else:
self.stackMin.append(self.min()) # 如果number大于最小值, 则重复压入当前最小值
self.stackData.append(number) # 数据直接放入数据栈中
"""
@return: An integer
"""
def pop(self):
# write your code here
if not len(self.stackData): # 先对数据栈进行判空
raise ValueError('your stack is empty!')
self.stackMin.pop()
return self.stackData.pop()
"""
@return: An integer
"""
def min(self):
# write your code here
if not len(self.stackMin):
raise ValueError('your stack is empty!')
return self.stackMin[-1] # 返回当前最小值, 相当于执行peek操作
@return: An integer
"""
def min(self):
# write your code here
if not len(self.stackMin):
raise ValueError('your stack is empty!')
return self.stackMin[-1] # 返回当前最小值, 相当于执行peek操作