返回

单调栈实现:剖析84. 柱状图中最大的矩形题目精髓,掌握最大矩形计算方法!

后端

算法世界中的精彩挑战:破解 84. 柱状图中最大的矩形

在算法世界中,84. 柱状图中最大的矩形无疑是一个备受推崇的经典难题。它不仅考验你的编程能力,更能锻炼你的算法思维。让我们踏上探索之旅,深入剖析这一迷人问题的精髓。

问题剖析

想象一个柱状图,其中每个柱子由数组中的一个元素表示。我们的目标是找出这个柱状图中最大的矩形,由紧密排列在一起、宽度相等的柱子组成。例如,对于柱状图 [2, 1, 5, 6, 2, 3],最大的矩形面积为 10。

单调栈:解题利器

解决此问题的关键在于单调栈。单调栈是一种数据结构,它遵循先入后出的原则,并且栈顶元素始终保持单调性。在我们的案例中,我们将使用单调递增栈,这意味着栈顶元素永远大于或等于其下方的元素。

算法步骤

  1. 初始化单调栈 :将第一个柱子的高度压入栈中。
  2. 遍历剩余柱子
    • 若当前柱子的高度大于栈顶元素,则直接压入栈中。
    • 若当前柱子的高度小于或等于栈顶元素,则弹出栈顶元素,并计算从该元素到当前元素形成的矩形面积。
    • 重复步骤 2,直到遍历完所有柱子。
  3. 弹出剩余元素 :将栈中剩余的元素依次弹出,并计算从该元素到最后一个元素形成的矩形面积。

代码示例(Python)

def largestRectangleArea(heights):
    stack = []
    max_area = 0

    for i, height in enumerate(heights):
        # 若当前柱子比栈顶柱子高,则直接入栈
        while stack and height < heights[stack[-1]]:
            # 计算以栈顶元素为宽度的矩形面积
            top = stack.pop()
            width = i if not stack else i - stack[-1] - 1
            max_area = max(max_area, heights[top] * width)

        # 将当前柱子入栈
        stack.append(i)

    # 计算栈中剩余元素组成的矩形面积
    while stack:
        top = stack.pop()
        width = len(heights) if not stack else len(heights) - stack[-1] - 1
        max_area = max(max_area, heights[top] * width)

    return max_area

复杂度分析

  • 时间复杂度:O(n),其中 n 为柱子的数量。
  • 空间复杂度:O(n),因为我们需要使用栈来存储柱子的索引。

结语

破解 84. 柱状图中最大的矩形问题,让我们领略了算法世界的魅力。运用单调栈这一利器,我们可以高效地计算出柱状图中最大的矩形面积。掌握这一技巧,将为我们在解决类似问题时开辟更广阔的道路。算法之旅充满挑战,但同时也是一次探索和成长的旅程。让我们继续前行,在算法的海洋中不断发现更多迷人的风景。

常见问题解答

  1. 为什么要使用单调栈?
    单调栈确保我们始终能找到当前柱子形成的最大矩形的宽度。
  2. 弹出栈顶元素时如何计算矩形面积?
    宽度由当前柱子的索引和栈顶元素的索引差值确定,高度为弹出元素的高度。
  3. 为什么在遍历完所有柱子后还要弹出剩余元素?
    这可以确保计算包含最后一个柱子的所有剩余矩形面积。
  4. 时间复杂度为什么是 O(n)?
    每个柱子最多入栈和出栈一次,因此总的操作次数为 O(n)。
  5. 空间复杂度为什么是 O(n)?
    栈中最多存储 n 个柱子的索引。