Python 直方图中矩形的最大面积-为什么需要堆栈?

Python 直方图中矩形的最大面积-为什么需要堆栈?,python,algorithm,computer-science,Python,Algorithm,Computer Science,考虑以下几点: 给定n个非负整数,表示直方图中宽度为1的条的高度,求直方图的最大面积矩形,即直方图中包含的最大面积矩形 关键思想是计算: R[i]=最大矩形的面积,其中条在i处为 矩形中的最小条(即宽度=H[i])左[i]=左 R[i]的最大边界,它是比H[i]大的最左边的条。 right[i]=R[i]的最右边边界,它是最右边的条 大于H[i] 我知道需要一个堆栈来计算right和left,但我认为我能够提供类似的解决方案,而无需使用堆栈: def max_area_rect(lst):

考虑以下几点:

给定n个非负整数,表示直方图中宽度为1的条的高度,求直方图的最大面积矩形,即直方图中包含的最大面积矩形

关键思想是计算:

R[i]=最大矩形的面积,其中条在i处为 矩形中的最小条(即宽度=H[i])左[i]=左 R[i]的最大边界,它是比H[i]大的最左边的条。 right[i]=R[i]的最右边边界,它是最右边的条 大于H[i]

我知道需要一个堆栈来计算
right
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
def最大面积(lst):
n=长度(lst)
右=[-1]*n
左=[-1]*n
右[n-1]=n
对于范围(n-2,-1,-1)内的i:
如果lst[i]>lst[i+1],则right[i]=i+1,否则为right[i+1]
左[0]=-1
对于范围(1,n)内的i:
左[i]=i-1如果lst[i-1]最大分辨率:
最大分辨率=分辨率
返回最大分辨率
#试验
打印(最大面积校正([4,2,1,8,6,8,5,2]))#预期结果:20

所以我的问题是:为什么我们需要一个堆栈?我的方法有效吗?

如你所说的
左[i]
的定义

left[i]=R[i]的最左侧边界,它是大于H[i]的最左侧条

您在代码中定义了什么

left[i] = i - 1 if lst[i - 1] < lst[i] else left[i - 1]
left[i]=i-1如果lst[i-1]
i、 e.如果左边的条形图更高,则将
left[i]=left[i-1]
。然而,这里的错误是
left[i-1]
存储的最左边的索引大于
lst[i-1]
,而不是
lst[i]


例如,在你输入的序列中,
left[i]
8不应该包括
6
,因此
left[i]
应该是
i
,但是
left[i]
5应该包括
6
,以及
8
,这就是你的代码忽略的地方。

。将5更改为6,输出不变。将4更改为3,输出更改为15。结果为20的计算结果是
res=(1+4)*4
,这是完全错误的,但恰好给出了正确的答案。此外,只需将相同的直方图反向输入算法即可:
[2,5,8,6,8,1,2,4]
。您的代码给出的结果为25。FWIW,您可以找到各种解决方案。