最大矩形面积问题
问题描述:
小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)
代码思路如下:
-
添加哨兵: 在数组末尾添加一个高度为 0 的柱子,方便处理剩余的柱子。
-
使用栈: 用一个栈来保存柱子的索引,栈中的柱子索引保持单调递增(从低到高)。
-
遍历柱子: 遍历每个柱子: 如果当前柱子比栈顶柱子矮,说明可以计算以栈顶柱子为高的矩形面积。 弹出栈顶元素,计算面积。
-
更新最大面积:每次计算面积后,检查是否比当前最大面积大,如果比当前最大面积大就更新最大面积。
然后返回最大面积即可