给定n个非负整数表示直方图宽度为1的条形高度,找到直方图的最大区域矩形,即直方图中包含的最大区域矩形。
关键的想法是计算:
R [i] = i处条形的最大矩形的面积为 矩形中的最小条(即宽度= H [i])左[i] =左边 R [i]的大多数边界,这是最左边的条大于H [i]。 right [i] = R [i]的最右边界,这是最右边的条 大于H [i]。
我已经知道需要一个堆栈来计算left
和def max_area_rect(lst):
n = len(lst)
right = [-1] * n
left = [-1] * n
right[n - 1] = n
for i in range(n - 2, -1, -1):
right[i] = i + 1 if lst[i] > lst[i + 1] else right[i + 1]
left[0] = -1
for i in range(1, n):
left[i] = i - 1 if lst[i - 1] < lst[i] else left[i - 1]
max_res = -1
for i in range(n):
right_len = right[i] - i -1
left_len = i - left[i] + 1
h = min(lst[right_len - 1], lst[left_len + 1])
res = (right_len + left_len) * h
if res > max_res:
max_res = res
return max_res
# test
print(max_area_rect([4, 2, 1, 8, 6, 8, 5, 2])) # expected result: 20
,但我认为我能够在不使用堆栈的情况下提供类似的解决方案:
{{1}}
所以我的问题是:为什么我们需要一个堆栈?我的方式有效吗?
答案 0 :(得分:3)
您提到的left[i]
的定义
left [i] = R [i]的最左边界,这是最左边的条大于H [i]
您在代码中定义的内容
left[i] = i - 1 if lst[i - 1] < lst[i] else left[i - 1]
即。如果左边的栏比较高,你就放left[i] = left[i-1]
。但是,这里的错误是left[i-1]
存储最左边的索引,该索引大于lst[i-1]
而不是lst[i]
。
例如,在您提供的输入中的序列6, 8, 5
中,{8}的left[i]
不应包含6
,因此left[i]
应为i
,但{{ 1}} for 5应包含left[i]
以及6
,这就是您的代码所忽略的内容。