单调递增栈能解决最大矩形问题,因其在每个元素出栈时可确定以该柱子为高的左右边界:左边界为栈中前一个元素下标(或-1),右边界为当前下标i(或n),从而准确计算最大矩形面积。

为什么单调递增栈能解决最大矩形问题
因为矩形高度受限于最短的那根柱子,而单调递增栈天然维护了「左侧第一个更小元素」的位置信息——栈中每个元素出栈时,它的左右边界就确定了:左边界是栈中前一个元素下标(或 -1),右边界是当前遍历到的下标。这恰好对应以该柱子为高的最大可扩展矩形。
栈里存下标而不是高度值
必须存 vector<int>::size_type</int> 类型的下标,不能存高度值。原因有二:一是需要通过下标访问原数组算宽度;二是当多个柱子高度相等时,只保留最靠左的下标即可,后续相同高度的柱子会在前面那个出栈时被“覆盖”处理,不影响结果。
常见错误是把 heights[i] 压栈,导致无法计算宽度、也无法定位左边界。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 初始化栈为
stack<int></int>,压入 -1 作为哨兵(方便处理第一个元素) - 遍历
heights,对每个i,若heights[i] < heights[stk.top()],则持续弹栈并计算面积 - 弹栈后,左边界是新栈顶(即
stk.top()),右边界是i,高度是heights[top],宽度是i - stk.top() - 1
别忘了处理栈里剩下的元素
遍历完数组后,栈中可能还剩一些下标,它们的右边界是整个数组末尾(即 n)。如果不手动清空,会漏掉以这些柱子为高的矩形。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
典型错误现象:输入 [2,1,2] 得到 2 而不是 3 —— 就是因为没处理栈中残留的下标 0 和 2。
正确做法:
- 在主循环结束后加一个 while 循环,用
n作为统一右边界 - 每次弹栈后,宽度按
n - stk.top() - 1算,注意此时栈不能为空(哨兵 -1 保证安全) - 推荐在原数组末尾补一个 0,避免单独写清理逻辑;但要注意这会改变原数组,需拷贝或用临时容器
边界和整数溢出容易被忽略
宽度计算 i - stk.top() - 1 中,如果栈为空(理论上不该发生,但哨兵缺失时会),直接访问 stk.top() 是未定义行为。另外,heights[i] 是 int,但面积可能是 long long 级别(比如 1e5 × 1e5),不转类型会导致溢出。
关键细节:
- 始终确保栈底有哨兵(如 -1),且初始化后立即压入
- 面积变量声明为
long long或用1LL * height * width强制提升 - 检查
stk.size() > 1再取stk.top(),比单纯判空更稳妥(因为哨兵占一个位置)
最麻烦的其实是调试时栈状态难追踪,建议在弹栈前打印 stk 和 i,比硬想快得多。

















