leetcode - 学习计划之剑指offer

Posted 一杯敬朝阳一杯敬月光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode - 学习计划之剑指offer相关的知识,希望对你有一定的参考价值。

剑指 Offer 30. 包含min函数的栈

力扣,定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

示例:

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

 解题

一:辅助栈,_memo记录元素,_help记录push后的最小元素,只需要将当前push进_memo的值与_help的栈顶元素比较取较小即可。出栈的时候,两个栈顶元素一起出,则pop后的栈顶元素依旧是原值,以及对应的最小值。

class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self._memo = []
        self._help = []
        self._help.append(float("inf"))


    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        self._memo.append(x)
        self._help.append(min(x, self._help[-1]))


    def pop(self):
        """
        :rtype: None
        """
        self._memo.pop()
        self._help.pop()


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


    def min(self):
        """
        :rtype: int
        """
        return self._help[-1]

二:只用一个栈

  • 存入(push):
    • _memo[-1] = 当前值x - 之前的最小值_min(_min【before push】)
    • 更新最小值_min = min(x, _min)
      •   当x >= _min【before push】时,_memo[-1] >= 0, _min【after push】= _min【before push】
      • 当x < _min【before push】时,_memo[-1] < 0, _min【after push】= x
  • 推出(pop):
    • _memo[-1](v) >= 0 时,_memo[-1]对应的push的原值x必然不小于之前的最小值,所以最小值无须更新
    • v < 0时,v 对应的push的原值x必然小于之前的最小值,也即当push之后,_min【after push】不再能代表最小值,需要还原该状态的最小值_min【before push】,该状态存入的栈顶元素v = x(_min【after push】) - 之前的最小值_min(_min【before push】),其中_min【after push】记录的就是_memo[-1]对应的push的原值x,则之前的最小值_min【before push】= _min【after push】- v
  • 栈顶top:
    •  _memo[-1] (v)>= 0时,此时的最小值_min【after push】就是push之前的最小值_min【before push】,所以依照存入反推x =  之前的最小值_min(_min【after push】)+ v
    • v < 0时,_min【after push】记录的就是_memo[-1]对应的push的原值x,则x = _min【after push】
class MinStack(object):
    def __init__(self):
        """
        initialize your data structure here.
        """
        self._memo = []
        self._min = None

    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        if len(self._memo) == 0:
            self._memo.append(0)
            self._min = x 
        else:
            self._memo.append(x - self._min)
            self._min = min(self._min, x)

    def pop(self):
        """
        :rtype: None
        """
        v = self._memo.pop()
        # v >= 0,代表加入的元素不大于未加入前的最小值,所以推出后,最小值不变
        # v < 0,代表加入的元素小于未加入前的最小值,则加入后最小值会更新为新加入的元素
           # 需要还原为未加入前的最小值
           # 存入栈的栈顶元素 = x[加入后最小值] - 未加入前的最小值
           # 未加入前的最小值(_min) = x[加入后最小值](_min) - 存入栈的栈顶元素(v)
        if v < 0: 
            self._min = self._min - v

    def top(self):
        """
        :rtype: int
        """
        v = self._memo[-1]
        if v >= 0:
            return v + self._min
        else:
            return self._min

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

 

以上是关于leetcode - 学习计划之剑指offer的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode剑指Offer学习计划第一天题目

Leetcode剑指Offer学习计划第二天题目

Leetcode剑指Offer学习计划第二天题目

Leetcode剑指Offer学习计划第二天题目

Leetcode剑指Offer学习计划第二天题目

Leetcode剑指Offer学习计划第一天题目