题目解析:16.最大矩形面积问题 | 豆包MarsCode AI刷题

42 阅读3分钟

问题描述

小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) 的最大值。


测试样例

样例1:

输入:n = 5, array = [1, 2, 3, 4, 5]
输出:9

样例2:

输入:n = 6, array = [5, 4, 3, 2, 1, 6]
输出:9

样例3:

输入:n = 4, array = [4, 4, 4, 4]
输出:16

思路一

只需要把所有能构成的矩形的大小都算出来就行了......

def solution(n, array):
    max_area = 0  # 用于记录最大面积
    
    # 遍历所有可能的 k 值
    for k in range(1, n + 1):
        # 遍历所有可能的起始位置 i
        for i in range(n - k + 1):
            # 计算从 i 开始的 k 个相邻元素的最小值
            min_height = min(array[i:i + k])
            # 计算面积
            area = k * min_height
            # 更新最大面积
            if area > max_area:
                max_area = area
    
    return max_area

思路二

为了高效地解决这个问题,我们可以利用单调栈的思想。单调栈是一种特殊的栈,其中的元素按照某种顺序排列(递增或递减)。在这个问题中,我们将使用一个递增的单调栈来存储边长的索引。

具体步骤

  1. 初始化

    • 创建一个空的栈 stack,用于存储边长的索引。
    • 初始化一个变量 max_area,用于记录最大矩形面积。
    • 在数组末尾添加一个为0的边长,确保所有边长都能被处理。
  2. 遍历数组

    • 遍历数组 heights,对于每个边长 heights[i]

      • 如果栈不为空且当前边长小于栈顶边长,说明栈顶边长的右侧第一个更小的边长已经找到。

      • 弹出栈顶边长的索引 top_index,并计算以 heights[top_index] 为高度的矩形面积。

      • 宽度计算:

        • 如果栈为空,说明左侧没有更短的边长,宽度为 i
        • 如果栈不为空,宽度为 i - stack[-1] - 1
      • 更新 max_area

  3. 处理剩余边长

    • 遍历结束后,栈中可能还有剩余的边长。这些边长的右边界是数组的最后一个元素之后的位置,左边界则是栈中下一个边长的位置。
    • 对于每个剩余的边长,计算其矩形面积并更新 max_area
  4. 返回结果

    • 返回 max_area
def largestRectangleArea(heights):
    stack = []
    max_area = 0
    heights.append(0)  
    for i, h in enumerate(heights):
        while stack and h < heights[stack[-1]]:
            height = heights[stack.pop()]
            width = i if not stack else (i - stack[-1] - 1)
            max_area = max(max_area, height * width)
        stack.append(i)
    return max_area