zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    hdu 4324(dfs)
    hdu 2376(求树上任意两点之间距离之和的平均值)
    hdu 3665(最短路)
    hdu 4463(最小生成树变形)
    hdu 2242(边双连通分量)
    hdu 2682(最小生成树)
    hdu 2444(二分图的判断以及求最大匹配)
    陶哲轩实分析命题6.4.12
    陶哲轩实分析习题8.3.4
    CantorBernsteinSchroeder定理的证明
  • 原文地址:https://www.cnblogs.com/nicetoseeyou/p/10397898.html
Copyright © 2011-2022 走看看