[LeetCode] 155. minStack 设计最小栈

注意:getMin()时间复杂度为O(1)

最原始的方法:

class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack=[]
        

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        # self.stack.push(x)  #无push函数,push操作是用append()函数实现
        self.stack.append(x)

    def pop(self):
        """
        :rtype: void
        """
        self.stack.pop()  #直接弹出最顶层元素
        

    def top(self):
        """
        :rtype: int
        """
        return self.stack[-1] 

    def getMin(self):
        """
        :rtype: int
        """
        # return min(self.stack())
        return min(self.stack)

可惜min()函数太慢

思路1:

使用2个栈,栈1记录进来的数,栈2记录目前的最小值。当有新数push进来的时候,如果栈2为空或者这个数小于栈2顶上的值,就把这个数推入栈2。当pop的数正好等于最小值时,说明当前栈内的最小值变化了,要弹出这个最小值,记录的下一个最小值来到栈顶。

栈2始终记录着栈1的当前最小值,故pop,push操作时也要一并考虑。

class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack=[]
        self.min_stack=[]

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        self.stack.append(x)
        # if self.min_stack==[] or x < self.min_stack[-1]
        if len(self.min_stack) == 0 or x <= self.min_stack[-1]:
            self.min_stack.append(x)

    def pop(self):
        """
        :rtype: void
        """
        if self.stack[-1]==self.getMin():  #函数前要带self
            self.min_stack.pop()
        return self.stack.pop()  
        

    def top(self):
        """
        :rtype: int
        """
        return self.stack[-1] 

    def getMin(self):
        """
        :rtype: int
        """
        return self.min_stack[-1]

运行时间降到了60ms 。    

时间复杂度分析:

getMin()和top()都是O(1).

 

思路2:

只使用1个栈,用一个变量min_val记录当前的最小值,将当前最小值一同入栈,为节省空间,仅在当前最小值更改时才入栈。所以该栈的push和pop实际上可能是两次。当新进来的数小于min_val时,把当前的min_val和新进来的数一起推入到栈,min_val变为这个新进来的数。当pop栈顶元素的时候,如果栈顶元素的值和min_val相等,那么就把它下面记录的之前最小值赋给min_val并弹出。

class MinStack(object):
 
    def __init__(self):
        self.min = 2147483647
        self.stack = []
 
    def push(self, x):
        if x <= self.min:
            self.stack.append(self.min)
            self.min = x
        self.stack.append(x)
 
    def pop(self):
        peak = self.stack.pop()
        if peak == self.min:
            self.min = self.stack.pop()
 
    def top(self):
        return self.stack[-1]
 
    def getMin(self):
        return self.min

不过此方法会出现重复值。

思路3:

也是使用1个栈,但栈中存的是当前值与最小值的差,用一个元素来记录,然后根据这个值可以计算出当前值和最小值。当栈顶元素为正时,表示当前元素比最小元素大,当前值为最小值+差值;当栈顶元素为负时,其表示的是当前元素值比之前最小值小,现在的最小值就是元素值。

class MinStack(object):
 
    def __init__(self):
        self.min = 2147483648
        self.stack = []
 
    def push(self, x):  
        if not self.stack:
            self.min = x
        self.stack.append(x - self.min)
        if x < self.min:
            self.min = x
 
    def pop(self):
        peak = self.stack.pop()
        if peak < 0:
            self.min = self.min - peak
 
    def top(self):
        if self.stack[-1] < 0:
            return self.min
        else:
            return self.min + self.stack[-1]
 
    def getMin(self):
        return self.min

 

posted @ 2019-02-18 20:54  Nice_to_see_you  阅读(234)  评论(0编辑  收藏  举报