定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
方法1:辅助栈
栈先进后出的性质的理解:
如果一个元素 a 在入栈时,栈里有其它的元素 b, c, d,那么无论这个栈在之后经历了什么操作,只要 a 在栈中,b, c, d 就一定在栈中,因为在 a 被弹出之前,b, c, d 不会被弹出。
因此,在操作过程中的任意一个时刻,只要栈顶的元素是 a,那么我们就可以确定栈里面现在的元素一定是 a, b, c, d。
那么,我们可以在每个元素
a
入栈时把当前栈的最小值m
存储起来。在这之后无论何时,如果栈顶元素是a
,我们就可以直接返回存储的最小值m。
因此,我们可以设计一个辅助栈,与元素栈同步插入、删除。当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,与当前元素比较得出最小值,将这个最小值插入辅助栈中。
代码如下:
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.l1 = []
self.l2 = [math.inf]
def push(self, x: int) -> None:
self.l1.append(x)
self.l2.append(min(x, self.l2[-1]))
def pop(self) -> None:
self.l2.pop()
self.l1.pop()
def top(self) -> int:
return self.l1[-1]
def min(self) -> int:
return self.l2[-1]
方法2:保存差值
我们不额外使用辅助栈,而是每次在插入元素时,都插入元素与当前栈中最小值的差值,然后再比较插入元素与当前最小值,更新最小值。
在删除元素时,如果栈顶的差值 < 0,说明最后一个插入的元素比之前的最小值(m')要小,且最小值已经更新为最后一个插入元素(m),因此在删除栈顶差值之前,我们需要将最小值变为 m'。我们知道栈顶的差值是通过 m-m' 得出的,因此我们只需进行 m - (m-m') 的运算就可恢复出之前的最小值。
代码如下:
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.stack = []
self.m = 0
def push(self, x: int) -> None:
if not self.stack:
self.stack.append(0)
self.m = x
else:
self.stack.append(x - self.m)
self.m = min(x, self.m)
def pop(self) -> None:
if self.stack[-1] < 0:
self.m = self.m - self.stack[-1]
self.stack.pop()
def top(self) -> int:
if self.stack[-1] < 0:
return self.m
return self.m + self.stack[-1]
def min(self) -> int:
return self.m