73.柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例1:
image

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例2:
image

输入: heights = [2,4]
输出: 4

提示:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

代码:

class Solution {
    public int largestRectangleArea(int[] heights) {
        //n为heights数组长度
        int n = heights.length;
        //left数组记录每个柱子左边第一个小于它的柱子的下标
        int[] left = new int[n];
        //right数组记录每个柱子右边第一个小于它的柱子的下标
        int[] right = new int[n];
        //使用单调栈(递增栈)来计算左右边界
        Deque<Integer> mono_stack = new ArrayDeque<Integer>();
        //从左向右遍历,计算左边界
        for (int i = 0; i < n; ++i) {
            //维护单调递增栈,弹出所有大于等于当前高度的柱子
            while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) {
                mono_stack.pop();
            }
            //如果栈为空,说明左边所有柱子都比当前高,左边界设为-1
            //否则,栈顶就是左边第一个小于当前高度的柱子
            left[i] = (mono_stack.isEmpty() ? -1 : mono_stack.peek());
            //将当前柱子下标入栈
            mono_stack.push(i);
        }
        //清空栈,准备计算右边界
        mono_stack.clear();
        //从右向左遍历,计算右边界
        for (int i = n - 1; i >= 0; --i) {
            //同样维护单调递增栈
            while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) {
                mono_stack.pop();
            }
            //如果栈为空,说明右边所有柱子都比当前高,右边界设为n
            //否则,栈顶就是右边第一个小于当前高度的柱子
            right[i] = (mono_stack.isEmpty() ? n : mono_stack.peek());
            //将当前柱子下标入栈
            mono_stack.push(i);
        }
        //计算最大矩形面积
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            //矩形宽度 = 右边界 - 左边界 - 1
            //矩形高度 = 当前柱子的高度
            ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);
        }
        //返回ans
        return ans;
    }
}
posted @ 2025-05-07 11:06  回忆、少年  阅读(22)  评论(0)    收藏  举报