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

95 阅读3分钟

最大矩形面积问题

一、问题重现

问题描述

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

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

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)的值为这 kk 个相邻元素中的最小值乘以 k。现在,小S希望你能帮他找出对于任意 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

二、解题思路

问题理解

我们需要在一个数组中找到任意 k 个相邻元素所能形成的最大矩形面积。这个矩形面积的计算方式是:k 个相邻元素中的最小值乘以 k

数据结构选择

由于我们需要频繁地查找最小值,并且需要遍历所有可能的 k 值(从 1 到 n),我们可以考虑使用单调栈,用于理清元素大小关系,并快速找到最小值。

算法步骤

  1. 初始化

    • 使用一个单调栈来存储数组元素的索引。
    • 使用一个变量 max_area 来记录最大矩形面积。
  2. 遍历数组

    • 对于每个元素,将其索引压入单调栈中。
    • 当栈顶元素大于当前元素时,弹出栈顶元素,并计算以栈顶元素为最小值的矩形面积。
  3. 计算面积

    • 对于每个弹出的栈顶元素,计算以该元素为最小值的矩形面积,并更新 max_area
  4. 处理剩余元素

    • 遍历结束后,栈中可能还有元素,依次弹出并计算面积。

三、代码实现

def solution(n, array):
    stack = []  # 单调栈,存储索引
    max_area = 0
    
    for i in range(n):
        while stack and array[stack[-1]] > array[i]:
            # 弹出栈顶元素并计算面积
            height = array[stack.pop()]
            width = i if not stack else i - stack[-1] - 1
            max_area = max(max_area, height * width)
        
        stack.append(i)
    
    # 处理剩余元素
    while stack:
        height = array[stack.pop()]
        width = n if not stack else n - stack[-1] - 1
        max_area = max(max_area, height * width)
    
    return max_area

四、算法复杂度分析

时间复杂度
  1. 遍历数组:代码中使用了一个 for 循环来遍历数组中的每个元素,时间复杂度为 O(n),其中 n 是数组的长度。

  2. 单调栈操作:在 for 循环中,每个元素最多会被压入和弹出栈一次。因此,单调栈的操作总时间复杂度为 O(n)

  3. 处理剩余元素:在遍历结束后,栈中可能还剩下一些元素,需要依次弹出并计算面积。这部分操作的时间复杂度也是 O(n)

整个算法的时间复杂度为 O(n)

空间复杂度
  1. 单调栈:单调栈最多存储 n 个元素的索引,空间复杂度为 O(n)

  2. 其他变量: 其他变量(如 max_area)的空间复杂度为 O(1)

整个算法的空间复杂度为 O(n)