返回

LeetCode 151:用 Python 实现常数时间复杂度的最小栈

Android

用 Python 征服 LeetCode 151:最小栈

在计算机科学的浩瀚世界里,栈是一种至关重要的数据结构,它遵循后进先出的 (LIFO) 原则。栈的操作很简单:push(压入)、pop(弹出)和 top(获取栈顶元素)。然而,LeetCode 151 抛出了一个更有挑战性的问题:设计一个栈,不仅支持这些基本操作,还能让你在恒定时间内检索栈中的最小元素。

深入 Python 实现

为了解决这个难题,我们将采用 Python 的优雅实现。我们的代码将围绕一个名为 MinStack 的类展开,它包含两个栈:一个用于存储所有元素(stack),另一个用于跟踪当前最小元素(min_stack)。

class MinStack:
    def __init__(self):
        self.stack = []
        self.min_stack = []

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

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

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

    def getMin(self):
        return self.min_stack[-1]

算法详解

push(x):

  • 将元素 x 压入主栈 stack。
  • 如果 min_stack 为空或 x 小于或等于 min_stack 的栈顶元素,则将 x 也压入 min_stack。

pop():

  • 如果栈顶元素等于 min_stack 的栈顶元素,则弹出 min_stack 的栈顶元素。
  • 弹出 stack 的栈顶元素。

top():

  • 返回 stack 的栈顶元素。

getMin():

  • 返回 min_stack 的栈顶元素,它是当前栈中的最小元素。

时间复杂度

如你所见,所有这些操作的平均时间复杂度都是 O(1),这意味着它们可以在恒定时间内执行。

示例:一探究竟

让我们通过一个示例来验证我们的实现:

stack = MinStack()
stack.push(-2)
stack.push(0)
stack.push(-3)
print(stack.getMin())  # 输出:-3
stack.pop()
print(stack.top())  # 输出:0
print(stack.getMin())  # 输出:-2

输出:

-3
0
-2

结论

我们已经成功地用 Python 实现了 LeetCode 151 中的最小栈。通过利用辅助栈来跟踪最小元素,我们能够在恒定时间内执行所有操作。掌握这个实现将赋予你解决更复杂算法问题的力量,例如需要快速检索最小或最大值的场景。

常见问题解答

Q1:辅助栈的用途是什么?
A1:辅助栈用于跟踪栈中的当前最小元素。

Q2:push() 操作如何保持 min_stack 的正确性?
A2:当压入一个新元素时,如果它是当前最小元素或更小,它会被压入 min_stack。

Q3:pop() 操作如何处理最小元素?
A3:如果弹出的元素是当前最小元素,则它也会从 min_stack 中弹出。

Q4:getMin() 操作如何确保返回正确的值?
A4:getMin() 返回 min_stack 的栈顶元素,该元素始终是栈中的最小元素。

Q5:这个实现可以处理负数吗?
A5:是的,这个实现可以处理正数、负数和零。