LeetCode-084-柱状图中最大的矩形

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

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

https://leetcode-cn.com/problems/largest-rectangle-in-histogram/

解题思路

固定高度,求宽度
也就是说以数组的每个元素,求出它们依次作为固定高度时能往左右扩散的最大宽度
也就是找出它们左右比它们低且最近的元素
利用单调栈,保持栈底 -> 栈顶是从小到大的
遍历一次数组,期间确定每个元素的左右边界
遍历元素
为了保持栈的单调性,循环操作直到

  • 当栈不为空时,如果当前元素小于栈顶元素
  • 说明栈顶元素找到了右边第一个比它小的元素, 于是当前元素就是它的右边界了
  • 随后栈顶元素弹出

当栈为空时, 说明当前元素是目前遍历过的元素中最小的, 所以左边界就是最左边

最左用 -1 表示

当栈不为空时, 则栈顶元素比当前元素小, 是它的左边界
确定完所有高度的左右边界后,遍历一次求出最大的面积

代码

class Solution {
    public int largestRectangleArea(int[] heights) {
        int n = heights.length;
        // 固定高度, 求宽度
        // 存储每一个高度对应的能往左往右伸展的宽度
        int[] left = new int[n]; // 左边界
        int[] right = new int[n]; // 右边界
        Arrays.fill(right, n);
        // 栈底 -> 栈顶
        //  小  ->  大
        Deque stack = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                // 当栈顶元素比当前元素大时
                // 说明栈顶元素找到了右边第一个比它小的元素, 于是当前元素就是它的右边界了
                right[stack.peek()] = i;
                stack.pop();
            }
            // 当栈为空时, 说明当前元素是目前遍历过的元素中最小的, 所以左边界就是最左边
            // 当栈不为空时, 则栈顶元素比当前元素小, 是它的左边界
            // 因为比当前元素大的都被弹出栈了
            left[i] = stack.isEmpty() ? -1 : stack.peek();
            stack.push(i);
        }
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);
        }
        return ans;
    }
}

你可能感兴趣的:(LeetCode-084-柱状图中最大的矩形)