155.最小栈

问题描述

设计一个支持 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.

问题思路

这道题最难的地方就在于getMin()函数的求法。
一开始我想的是利用一个辅助变量来存储最小的数。当进栈时,判断入栈变量与辅助变量的大小关系,然后改变辅助变量的值;当出栈时,如果出栈变量是最小的值时,则遍历栈,找到最小元素赋值给辅助变量,但是很显然,这种做法在使用pop()方法时的时间复杂度是O(n),不是很可取。
之后我又查阅了其他同学的代码,发现他们利用了一个辅助栈,采用了“空间换时间”的策略,用来达到O(1)的时间复杂度。
具体做法如下:

  • 定义双栈,一个用来存储数据,另外一个用来存储比第一个数以及比它更小数据。
  • 当入栈时,首先检查辅助栈是否为空和辅助栈中的最后一个元素是否比入栈元素大,如果比它大,则把入栈元素放入双栈,否则只放入数据栈。
  • 当出栈时,检查出栈元素是否为最小元素,如果是,则出双栈,否则只需要数据栈元素出栈即可。

具体代码

代码1(暴力解法)

class MinStack(object):
    stack = []
    min = None

    def __init__(self):
        """
        initialize your data structure here.
        """

    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        self.stack.append(x)
        if self.min == None or x < self.min:
            self.min = x

    def pop(self):
        """
        :rtype: None
        """
        item = self.stack.pop()
        if item == self.min:
            localMin = None
            for i in self.stack:
                if localMin == None or i < localMin:
                    localMin = i
            self.min = localMin
        return item

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

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



# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

代码2(辅助栈)

class MinStack(object):
    stack1 = []
    stack2 = []
    min = None

    def __init__(self):
        """
        initialize your data structure here.
        """

    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        self.stack1.append(x)
        if not self.stack2 or x <= self.stack2[-1]:
            self.stack2.append(x)

    def pop(self):
        """
        :rtype: None
        """
        if self.stack1:
            item = self.stack1.pop()
            if item == self.stack2[-1]:
                self.stack2.pop()
            return item
        return False
    def top(self):
        """
        :rtype: int
        """
        if self.stack1:
            return self.stack1[-1]

    def getMin(self):
        """
        :rtype: int
        """
        if self.stack2:
            return self.stack2[-1]
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 查看题目详情可点击此处。 题目 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。...
    Cloneable阅读 245评论 0 0
  • 题目描述 [最小栈] 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。 push...
    一只可爱的柠檬树阅读 104评论 0 1
  • 最小栈 题目 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。 push(x) ...
    饮酒醉回忆阅读 204评论 0 1
  • 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。push(x) -- 将元素 x...
    genggejianyi阅读 207评论 0 0
  • 看了白蛇缘起这部动漫吗?我看了看完之后觉得不过瘾而在重新看的话就没有意思。它哪里好看了,好看的是它的特效。人物初看...
    小怪猫阅读 294评论 0 4