📅  最后修改于: 2023-12-03 15:28:43.389000             🧑  作者: Mango
给定一个数组 arr[]
,其中每个元素表示该位置上的建筑物的高度。 它被表示为一个直方图中。 找到这个直方图中可以容纳的最大矩形的面积。
例如,在下面的图中,最大矩形的面积是 6*4=24
。
_ _
| | _ _
_ _ | | | |
| | | | | |
| | | | | |
| | | | | |
-----------------
def getMaxArea(arr: List[int]) -> int:
pass
arr
: 长度为 $n$ 的整数列表,$0 \leq n \leq 10^6$,$0 \leq arr_i \leq 10^9$assert getMaxArea([6, 2, 5, 4, 5, 1, 6]) == 12
这是一个非常经典的问题,称为直方图中的最大矩形。一个简单的思路是穷举矩形,计算每个矩形的面积,取面积最大的一个。时间复杂度为 $O(n^3)$,无法通过本题。
更好的做法是,维护一个单调递增的栈。栈中维护的是直方图中的下标,而非直方图高度。依次遍历直方图中的每个高度,对于每个高度,它可以组成的最大面积的矩阵只可能在两种情况下出现:
top
所在的高度更高时,将其入栈。top
所在的高度更低时,栈顶元素 top
的最大面积的矩阵已经找到。弹出栈顶元素 top
,则其对应的矩阵的宽为 $i - stack[-1] - 1$,其中 i
为当前高度在直方图中的下标,stack[-1]
表示栈中下一个下标的前一个下标。因此,只需将每个高度分别入栈和弹栈,时间复杂度为 $O(n)$,可以通过本题。
具体细节可以见代码实现。
from typing import List
def getMaxArea(arr: List[int]) -> int:
stack = [-1]
max_area = 0
n = len(arr)
for i in range(n):
while stack[-1] != -1 and arr[stack[-1]] > arr[i]:
top = stack.pop()
max_area = max(max_area, arr[top] * (i - stack[-1] - 1))
stack.append(i)
while stack[-1] != -1:
top = stack.pop()
max_area = max(max_area, arr[top] * (n - stack[-1] - 1))
return max_area