栈的最小值

请设计一个栈,除了常规栈支持的pop与push函数以外,还支持min函数,该函数返回栈元素中的最小值。
执行push、pop和min操作的时间复杂度必须为O(1)。

示例:
        MinStack  minStack  =  new  MinStack();
        minStack.push(-2);
        minStack.push(0);
        minStack.push(-3);
        minStack.getMin();      -->  返回  -3.
        minStack.pop();
        minStack.top();            -->  返回  0.
        minStack.getMin();      -->  返回  -2.

自我解答

        push,  pop  等都很容易实现O(1),  但怎么能不迭代获取最小值呢?
        在每次  push  和  pop  的过程其实就已经访问过每个元素了,可以设置一个变量,
        记录最小值,每次  push  检查更新最小值,但  每次  pop  时,需要检查出栈的是不是
        最小值,如果是,则需要迭代寻找最小值了,这种情况  pop  的时间复杂就是  O(n)了,
        有点不符合题意。但执行效率依然很高
执行用时:60  ms,  在所有  Python3  提交中击败了99.90%  的用户
内存消耗:16.5  MB,  在所有  Python3  提交中击败了53.66%的用户

class MinStack():

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

    def push(self, x: int) -> None:
        self.stack.append(x)
        if self.min_x is None or x < self.min_x:
            self.min_x = x

    def pop(self) -> None:
        if self.stack.pop() == self.min_x:
            self.min_x = min(self.stack) if self.stack else None

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

    def getMin(self) -> int:
        return self.min_x
题解

        题解是用两个栈实现的。
        我思考过添加一个队列,把所有元素从大到小排列,这样最后一个就是最小值了。
        但是这样在执行效率太低了,不仅每次  push  都需要插入排序,而且每次  pop  时,如果  pop的
        是最小值还好处理,但如果  pop  的不是最小值,就还需要从查找删除。  这样显然是行不通的。

        那么到底怎么做呢?  题解使用了非常巧妙的方式:
                设置变量:  self.stack  =  [],  用来储存所有数据;
                设置变量:  self.min_stack  =  [],  只储存  “<=  栈顶值的数据“  或  ”当此栈为空时储存任何数据“

        我一开始是惯性思维,想着应该对所有数排序。
        比如依次将  5,3,4  压入栈中:
                如果把所有数都存入  min_stack,  会是这样  [5,4,3],  会想到,3  是最小的,推出  3  后,
                最小值理应是第二小的  4,  所以  4  应该也放到  min_stack  中的。但其实是多余的,
                因为推出  3  时,4  早就没了。  
                
        这也正是  self.min_stack  的巧妙之处,只需要储存  ”更小的数“,之后如果再遇到”第二小的数“,
        对于业务:getMin  来说,都是没有意义的。
        

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

    def push(self, x: int) -> None:
        self.stack.append(x)
        if not self.min_stack or x <= self.min_stack[-1]:
            self.min_stack.append(x)

    def top(self) -> int:
        return self.stack[-1] if self.stack else None


    def pop(self) -> None:
        if self.stack:
            num = self.stack.pop(-1)
            if num == self.min_stack[-1]:
                self.min_stack.pop(-1)

    def getMin(self) -> int:
        return self.min_stack[-1] if self.min_stack else None

        虽然没有“自我解答”中的思路好理解,但真正实现了  O(1)

原题链接:https://leetcode-cn.com/problems/min-stack-lcci