Leetcode 155:最小栈(超详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/85618453

设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) – 将元素 x 推入栈中。
  • pop() – 删除栈顶的元素。
  • top() – 获取栈顶元素。
  • getMin() – 检索栈中的最小元素。

示例:

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

解题思路

由于问题中没有讲述对于错误输入的操作,所以我们默认没有错误输入。最简单的思路就是对数组的操作

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

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        self.data.append(x)

    def pop(self):
        """
        :rtype: void
        """
        self.data.pop()

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

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

但是这个getMin无法在常数时间内找到最小值,所以我们可以添加一个变量,记录堆中的最小值。

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        if x < self.min_val:
            self.min_val = x        
        self.data.append(x)

我们的pop操作也应该随之改变,如果恰好弹出最小值呢?这要怎么办?一种策略就是再建一个栈,用于存放最小值。

class MinStack(object):
    def __init__(self):
        """
        initialize your data structure here.
        """
        self.s1 = [] 
        self.s2 = []

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        if not self.s2 or x <= self.getMin():
            self.s2.append(x) 
            
        self.s1.append(x)

    def pop(self):
        """
        :rtype: void
        """
        if self.s1[-1] == self.getMin():
            self.s2.pop()
            
        self.s1.pop()

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

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

还有一种策略是在push的时候,我们也将min_val同时push进去,然后在pop的时候判断min_valdata最后一个元素是不是相同,相同的话(恰好要弹出最小元素),我们就先pop出最小元素,然后更新此时的min_val(此时应该是data[-1]),然后再进行一次pop。例如

此时我们要考虑加入-3了,因为-3 < -2

我们首先将min_val,也就是-2压入,然后再压入-3。此时更新我们的min_val=-3

def push(self, x):
    """
    :type x: int
    :rtype: void
    """
    if x <= self.min_val:
        self.data.append(self.min_val)
        self.min_val = x

    self.data.append(x)

def pop(self):
    """
    :rtype: void
    """
    if self.data[-1] == self.min_val:
        self.data.pop()
        self.min_val = self.data[-1]
        self.data.pop()
    else:
        self.data.pop()

总的思路就是当访问到的元素最小时,我们一定先要保存上一次的最小元素,然后再更新最小元素。

reference:

https://leetcode.com/problems/min-stack/discuss/49016/C%2B%2B-using-two-stacks-quite-short-and-easy-to-understand

https://leetcode.com/problems/min-stack/discuss/49031/Share-my-Java-solution-with-ONLY-ONE-stack

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/85618453