You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

直方图最大矩形面积:为何需用栈?我的解法是否有效?

直方图最大矩形面积:栈解法的必要性与你的代码分析

首先直接给出结论:你的当前解法是无效的——运行你提供的测试用例[4, 2, 1, 8, 6, 8, 5, 2],你的代码返回12,和预期的20不符。接下来我们拆解问题,逐一解答你的疑问:

一、为什么通常用栈解决这个问题?

我们的核心思路确实是计算以每个柱子为最矮柱的最大矩形面积,这需要为每个柱子找到:

  • left_bound[i]:左侧第一个高度小于H[i]的柱子索引(不存在则为-1)
  • right_bound[i]:右侧第一个高度小于H[i]的柱子索引(不存在则为数组长度n)

此时以H[i]为高度的矩形宽度是right_bound[i] - left_bound[i] - 1,面积为H[i] * (right_bound[i] - left_bound[i] - 1)。

栈的价值在于它能以O(n)线性时间完成所有边界的计算:
栈会维护一个单调递增的索引序列,保证栈顶对应的柱子高度是栈中最小的。当遇到一个高度小于栈顶的柱子时,我们就能确定栈顶柱子的右边界是当前索引,左边界是栈顶的前一个元素(或-1),可以直接计算该柱子的面积,同时弹出栈顶,直到栈重新保持单调递增。

这种方法每个柱子入栈、出栈各一次,时间效率极高,能轻松处理大规模数据(比如n=10^5的场景),而暴力遍历找边界的方法是O(n²),数据量大时会直接超时。

二、你的解法存在的核心问题

1. 边界数组(left/right)的计算逻辑错误

你定义的right[i]是“右侧首个大于H[i]的柱”,这本身就和核心思路相悖——我们需要的是首个小于H[i]的柱来确定边界。而且你的计算逻辑:

right[i] = i + 1 if lst[i] > lst[i + 1] else right[i + 1]

只能处理连续递减的简单场景,遇到中间有更大元素的情况就会出错。比如测试用例中索引2的柱子值为1,右侧所有元素都比它大,正确的右边界应该是8(数组长度),但你的代码会把right[2]设为right[3]=4,完全错误。

同样,left数组的计算逻辑也无法正确处理所有情况,比如数组[2,3,1]中,索引2的柱子值为1,左侧所有元素都比它大,正确左边界是-1,但你的代码会把left[2]设为left[1]=0,明显错误。

2. 面积计算逻辑完全偏离核心思路

你代码中计算面积的部分:

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

这段逻辑完全脱离了“以当前柱为最矮柱”的核心,right_len、left_len的计算没有意义,h取的是两个无关位置的最小值,导致计算出的面积和实际情况毫无关联。比如测试用例中索引5的柱子值为8,实际面积是8*1=8,但你的代码计算出的结果是4,完全错误。

三、不用栈的有效解法参考

如果想不用栈,暴力法是最直接的有效实现(虽然时间复杂度高),它通过对每个柱子向左、向右遍历找到正确边界:

def max_area_rect(lst):
    n = len(lst)
    max_area = 0
    for i in range(n):
        # 找左侧第一个小于当前高度的索引
        left = i
        while left > 0 and lst[left-1] >= lst[i]:
            left -= 1
        # 找右侧第一个小于当前高度的索引
        right = i
        while right < n-1 and lst[right+1] >= lst[i]:
            right += 1
        # 计算面积并更新最大值
        area = lst[i] * (right - left + 1)
        max_area = max(max_area, area)
    return max_area

这个实现能得到正确结果,但对于n>10^4的数组会超时,这时候栈解法的优势就体现出来了。

内容的提问来源于stack exchange,提问作者socksocket

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:33:49