返回

「栈」揭秘 LeetCode 84:柱状图中的最大矩形,独创视角助你攻克难关

前端

引言:算法与数据结构的完美邂逅

在计算机科学的浩瀚领域中,算法与数据结构犹如相辅相成的两翼,共同构筑了软件开发和问题求解的基础。算法为我们提供了解决问题的步骤和策略,而数据结构则为算法提供了高效组织和处理数据的框架。在今天这道题目的解析中,我们将亲身体验栈这一经典数据结构的强大威力,见证算法与数据结构的完美邂逅,开启算法思维的全新篇章。

题目剖析:柱状图中的最大矩形

「柱状图中的最大矩形」这道题目了一个由 n 个非负整数构成的数组,每个整数代表柱状图中一根柱子的高度。我们的目标是求出柱状图中可以容纳的最大矩形面积。乍一看,这似乎是一个复杂的问题,但运用适当的算法和数据结构,我们可以将问题分解成更容易处理的部分。

栈的登场:单调递增栈的妙用

栈是一种先进后出的数据结构,它就像一个垂直放置的弹簧,后放入的元素会优先弹出。在解决这道题时,我们将用到一个单调递增栈。顾名思义,单调递增栈中的元素始终保持从小到大的顺序。换句话说,栈顶元素始终是栈中最大的元素。

我们如何利用单调递增栈来解决这道题呢?首先,我们将柱状图中的每个柱子看作一个矩形的宽度。然后,我们将柱状图从左到右扫描一遍。对于每个柱子,我们检查栈顶元素是否比当前柱子矮。如果是,则说明当前柱子可以与栈顶元素形成一个矩形,其高度为栈顶元素的高度,宽度为当前柱子和栈顶元素之间的距离。我们将这个矩形面积压入栈中。

示例解析:步步为营,直击本质

为了更好地理解这一过程,我们来看一个具体的示例。假设柱状图的高度为 [2, 1, 5, 6, 2, 3]。

从左到右扫描柱状图:

  • 对于第一个柱子(高度为 2),栈为空,因此我们直接将 2 压入栈中。
  • 对于第二个柱子(高度为 1),它比栈顶元素 2 小,因此我们计算矩形面积:2 x (2 - 0) = 4。我们弹出栈顶元素 2,并将 4 压入栈中。
  • 对于第三个柱子(高度为 5),它比栈顶元素 4 大,因此我们直接将 5 压入栈中。
  • 对于第四个柱子(高度为 6),它比栈顶元素 5 大,因此我们直接将 6 压入栈中。
  • 对于第五个柱子(高度为 2),它比栈顶元素 6 小,因此我们计算矩形面积:6 x (4 - 0) = 24。我们弹出栈顶元素 6 和 5,并将 24 压入栈中。
  • 对于第六个柱子(高度为 3),它比栈顶元素 24 小,因此我们计算矩形面积:24 x (2 - 0) = 48。我们弹出栈顶元素 24,并将 48 压入栈中。

最终,栈中只包含一个元素:48,这正是柱状图中可以容纳的最大矩形面积。

代码实现:Python 解法,优雅简洁

def maximal_rectangle(heights):
    """
    :type heights: List[int]
    :rtype: int
    """
    stack = []
    max_area = 0
    
    for i, height in enumerate(heights):
        while stack and height < heights[stack[-1]]:
            h = heights[stack.pop()]
            w = i if not stack else i - stack[-1] - 1
            max_area = max(max_area, h * w)
        stack.append(i)
    
    while stack:
        h = heights[stack.pop()]
        w = len(heights) if not stack else len(heights) - stack[-1] - 1
        max_area = max(max_area, h * w)
    
    return max_area

总结:算法之美,尽在掌控

通过这道题目的解析,我们领略了算法与数据结构的巧妙结合。栈这一简单却强大的数据结构,在解决这道难题中发挥了至关重要的作用。通过单调递增栈,我们可以高效地计算出柱状图中可以容纳的最大矩形面积。

算法之美,在于其简洁、优雅和高效。它不仅为我们提供了解决问题的方法,更教会我们如何清晰地思考和严谨地分析。希望这道题目的解析能激发你对算法的兴趣,助你踏上算法思维的进阶之旅。