最大矩形面积问题详解 | 豆包MarsCode AI刷题

86 阅读2分钟

最大矩形面积问题

问题描述:

小S最近在分析一个数组 h1,h2,...,hNh1​,h2​,...,hN​,数组的每个元素代表某种高度。小S对这些高度感兴趣的是,当我们选取任意 kk 个相邻元素时,如何计算它们所能形成的最大矩形面积。

对于 kk 个相邻的元素,我们定义其矩形的最大面积为:

R(k)=k×min(h[i],h[i+1],...,h[i+k−1])R(k)=k×min(h[i],h[i+1],...,h[i+k−1])

即,R(k)R(k) 的值为这 kk 个相邻元素中的最小值乘以 kk。现在,小S希望你能帮他找出对于任意 kk,R(k)R(k) 的最大值。

这道题我做的时候一开始想的就是可以使用暴力来解决。

代码如下:

# 最大矩形面积问题
def solution(n, array):
    max_area = 0

    for k in range(1, n + 1):
        for i in range(n - k + 1):
            min_height = min(array[i:i + k])
            area = k * min_height
            max_area = max(max_area, area)
    
    return max_area
  • 时间复杂度:O(n^3)
  • 空间复杂度:O(1)

直接通过两个for循环来遍历所有 k 和子数组,然后使用 min(array[i:i + k]) 获取当前子数组的最小高度,再用 k 乘以最小高度计算当前矩形的面积。使用 max(max_area, area) 更新最大面积即可。

但是暴力的时间复杂度比较高,所以我在想有没有时间复杂度比较低的方法,问了一下豆包MarsCode AI这道题除了使用暴力还有没有更好的方法,然后豆包MarsCode AI给了我第二种方法:单调栈,即通过使用栈来高效地计算最大矩形面积,避免了使用双重循环,降低了时间复杂度。

代码如下:

def solution(n, array):
    heights = array + [0]  
    stack = []  
    max_area = 0
    for i in range(len(heights)):
        while stack and heights[i] < 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)
    return max_area
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

代码思路如下:

  1. 添加哨兵: 在数组末尾添加一个高度为 0 的柱子,方便处理剩余的柱子。

  2. 使用栈: 用一个栈来保存柱子的索引,栈中的柱子索引保持单调递增(从低到高)。

  3. 遍历柱子: 遍历每个柱子: 如果当前柱子比栈顶柱子矮,说明可以计算以栈顶柱子为高的矩形面积。 弹出栈顶元素,计算面积。

  4. 更新最大面积:每次计算面积后,检查是否比当前最大面积大,如果比当前最大面积大就更新最大面积。

然后返回最大面积即可