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

101 阅读2分钟

问题描述

小S最近在分析一个数组 sh1,h2,...,hNsh_1,h_2,..., h_N,数组的每个元素代表某种高度。小S对这些高度感兴趣的是,当我们选取任意 kk 个相邻元素时,如何计算它们所能形成的最大矩形面积。 对于 kk 个相邻的元素,我们定义其矩形的最大面积为: R(k)=k×min(h[i],h[i+1],...,h[i+k1])R(k) = k\times min(h[i], h[i + 1], ..., h[i + k - 1]) 即,R()R() 的值为这 kk 个相邻元素中的最小值乘以 kk。现在,小S希望你能帮他找出对于任意 kkR(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

思路:

  1. 单调栈:我们维护一个栈,栈中的元素是数组的索引,栈中的高度元素从栈底到栈顶是递增的。
  2. 遍历:遍历数组,对于每个元素,判断当前元素是否小于栈顶元素。如果小于,则弹出栈顶元素,计算以该元素为高度的矩形面积。如果大于或等于栈顶元素,则将当前元素的索引压入栈中。
  3. 结束处理:当遍历完成后,栈中可能还剩下一些元素,需要处理这些元素,计算出它们所能构成的最大矩形面积

代码如下:

def solution(n, array):
stack = []
max_area = 0

for i in range(n):
    # 处理当前元素,保证栈中的元素是递增的
    while stack and array[stack[-1]] > array[i]:
        h = array[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 = array[stack.pop()]
    w = n if not stack else n - stack[-1] - 1
    max_area = max(max_area, h * w)

return max_area


if __name__ == "__main__":
# Add your test cases here

print(solution(5, [1, 2, 3, 4, 5]) == 9)

时间复杂度:

  • 由于每个元素最多被压入栈一次,并且最多被弹出一次,时间复杂度是 (O(n)),相较于暴力法的 (O(n^2)),效率大大提高

举例:

假设 array = [2, 1, 5, 6, 2, 3],运行该算法的过程如下:

  • 遇到 2,压栈;
  • 遇到 1,弹出 2 计算面积,更新最大面积,压 1;
  • 遇到 5,压栈;
  • 遇到 6,压栈;
  • 遇到 2,弹出 6、5 计算面积,更新最大面积,压 2;
  • 遇到 3,压栈,最终处理栈中剩余元素,得到最大矩形面积。

这个优化方案是解决此问题的经典方法,非常高效。