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

44 阅读2分钟

前言:剑指offer刷题系列

问题:

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 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.

思路:

栈是一种遵循 后进先出(LIFO)原则的数据结构。这个类有以下几个方法:

  • 先初始化一个空栈和一个空的最小值栈。
  • push(x: int):将元素 x 推入栈中。如果最小值栈为空或者 x 小于等于最小值栈的栈顶元素,则将 x 也推入最小值栈。
  • pop():删除栈顶元素。如果栈顶元素等于最小值栈的栈顶元素,则也删除最小值栈的栈顶元素。
  • top() -> int:返回栈顶元素。
  • min() -> int:返回最小值栈的栈顶元素。

这个类的实例可以用来存储整数,并且可以在常数时间内检索到最小值。

时间复杂度O(1) : push(), pop(), top(), min() 四个函数的时间复杂度均为常数级别。 空间复杂度 O(N) : 当共有 N 个待入栈元素时,辅助栈 B 最差情况下存储 N 个元素,使用 O(N) 额外空间。

基于上述思考,代码如下:

class MinStack:
    def __init__(self):
        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 pop(self) -> None:
        if self.stack[-1] == self.min_stack[-1]:
            self.min_stack.pop()
        return self.stack.pop()

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

    def min(self) -> int:
        return self.min_stack[-1]

执行结果如下图:

image-20230918001059692.png

学到的知识点:

  1. 学会如何使用 Python 语言实现一个包含 min 函数的栈。

  2. 学会如何在栈中实现 pushpoptopmin 函数,且它们的时间复杂度都是 O(1)。

  3. 学会如何使用两个栈来实现 min 函数,其中一个栈用于存储栈中的元素,另一个栈用于存储当前最小元素。

  4. 学会如何在 push 方法中判断新元素是否比当前最小元素还小,并将其同时压入最小元素栈中。

  5. 学会如何在 pop 方法中判断弹出的元素是否是当前最小元素,并同时弹出最小元素栈的栈顶元素。

    这道题考察我们学过的数据结构--栈,总的来说,还是比较简单的,就是要理解栈的实现。