柱状图中最大的矩形

GitHub跳转原题关系图返回列表

单调栈弹出时左右第一个更矮位置决定宽度,高度乘宽度即为面积,末尾补 0 清算剩余。

OJ: leetcodecn

题目 ID: largest-rectangle-in-histogram

难度:提高+/省选-

标签:单调栈

日期: 2026-07-29 12:12

题意

给定柱状图的高度数组,求能勾勒出的最大矩形面积。

思路

单调栈保存柱子下标,栈底到栈顶高度递增。弹出时,弹出的高度 h 就是被结算柱子的高度,左边界是弹出后新栈顶(第一个更矮的柱),右边界是当前扫描位置 i(第一个右边更矮的柱),宽度 = i - l - 1

末尾补一个虚拟的 0 高度柱,确保所有栈中剩余柱子都被结算。

代码

cpp
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    int largestRectangleArea(vector<int> &heights) {
        heights.push_back(0);
        stack<int> st;
        int ans = 0;
        for (int i = 0; i < (int)heights.size(); i++) {
            while (!st.empty() && heights[st.top()] > heights[i]) {
                int h = heights[st.top()];
                st.pop();
                int l = st.empty() ? -1 : st.top();
                ans = max(ans, h * (i - l - 1));
            }
            st.push(i);
        }
        heights.pop_back();
        return ans;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int &x : a)
        cin >> x;
    cout << Solution().largestRectangleArea(a) << '\n';
    return 0;
}
python
#!/usr/bin/env python3
from typing import List


class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        heights.append(0)
        st = []
        ans = 0
        for i, h in enumerate(heights):
            while st and heights[st[-1]] > h:
                hh = heights[st.pop()]
                l = st[-1] if st else -1
                ans = max(ans, hh * (i - l - 1))
            st.append(i)
        heights.pop()
        return ans


def main():
    n = int(input())
    a = list(map(int, input().split()))
    print(Solution().largestRectangleArea(a))


if __name__ == "__main__":
    main()

复杂度

  • 时间复杂度:O(n)O(n),每个柱子最多入栈出栈一次。
  • 空间复杂度:O(n)O(n),栈最多存所有下标。

总结

柱状图最大矩形是单调栈的经典应用:弹出时左右第一个更矮的位置决定宽度。末尾补 0 是关键技巧,确保结算所有柱子。