📌  相关文章
📜  在O(1)时间和O(1)额外空间中查找堆栈中的最大值(1)

📅  最后修改于: 2023-12-03 15:37:36.775000             🧑  作者: Mango

在O(1)时间和O(1)额外空间中查找堆栈中的最大值

当涉及到堆栈时,我们经常需要找到堆栈中的最大元素(或最小元素)。在常规情况下,我们会扫描整个堆栈以查找这些元素,这将导致O(n)时间复杂度。但是,可以在O(1)时间和O(1)额外空间的情况下实现堆栈最大元素的查找,下面将介绍如何实现此功能。

思路

我们可以在堆栈上保留当前最大元素,并修改每个元素的值以包含它在栈中的先前最大值。我们可以使用辅助堆栈来维护这些先前最大值。

例如,如果我们将以下元素压入堆栈:

5, 3, 9, 7, 2, 4

我们将在辅助堆栈中维护以下最大元素:

5, 5, 9, 9, 9, 9

现在,我们可以在O(1)时间内查找堆栈中的最大值,只需查看辅助堆栈的顶部元素即可。每次我们在堆栈中压入新元素时,我们将该元素与辅助堆栈的顶部元素进行比较,并将较大的值推入辅助堆栈。

当堆栈中的元素弹出时,我们还必须从辅助堆栈中弹出元素以匹配它们。因此,我们的堆栈push和pop操作的时间复杂度仍然为O(1)。

代码示例

下面是用Python语言实现上述思路的代码示例:

class MaxStack:
    def __init__(self):
        self.stack = []
        self.max_stack = []

    def push(self, x: int) -> None:
        self.stack.append(x)
        if not self.max_stack or x >= self.max_stack[-1]:
            self.max_stack.append(x)

    def pop(self) -> None:
        if self.stack[-1] == self.max_stack[-1]:
            self.max_stack.pop()
        self.stack.pop()

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

    def get_max(self) -> int:
        return self.max_stack[-1]

在这个类中,我们保留两个堆栈:一个是实际的堆栈,另一个是辅助堆栈,用于存储先前的最大元素。

我们实现了四个操作:

  • push:将元素压入实际堆栈,并在辅助堆栈中维护先前的最大元素。如果一个元素等于或大于辅助堆栈的顶部元素,则将该元素推入辅助堆栈中。
  • pop:弹出堆栈中的元素,并从辅助堆栈中弹出匹配的元素。
  • top:返回堆栈顶部的元素。
  • get_max:在O(1)时间内返回堆栈中的最大元素,只需返回辅助堆栈的顶部元素即可。
结论

我们演示了如何在O(1)时间和O(1)额外空间的情况下查找堆栈中的最大元素。该方法使用辅助堆栈来维护先前的最大值,并处理堆栈的push和pop操作。下次当你需要查找堆栈中的最大元素时,尝试使用这个技巧,它将显著提高你的代码效率。