LC084-柱状图中最大的矩形

84. 柱状图中最大的矩形

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

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

img

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]

img

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

输入: [2,1,5,6,2,3]
输出: 10

方法一:暴力破解法

遍历到每一个柱子的左右,由这个柱子向两侧延申,直到遇到比其更小的h柱子,确定左右边界.对应的面积为w*h

public class LEE084L {
    public int largestRectangleArea(int[] heights) {
        int res = 0;
        int n = heights.length;
        for (int mid = 0; mid < n; mid++) {
            int midHeight = heights[mid];
            int a = mid;
            int b = mid;
            while (a - 1 >= 0 && heights[a - 1] >= midHeight) {
                a--;
            }
            while (b + 1 < n && heights[b + 1] >= midHeight) {
                b++;
            }
            res = Math.max(res, (b - a + 1) * midHeight);
        }
        return res;
    }
}

方法二:单调栈

  1. 单调栈分为单调递增,单调递减

  2. 操作规则(下面都以单调递增栈为例)

    如果新的元素比栈顶大,就入栈

    如果新的元素比栈顶小,就弹出栈顶的元素,直到栈顶比新元素小.也就是新元素大

  3. 加入这样一个规则之后,会有什么效果

    栈内的元素是递增的
    当元素出栈时,说明这个新元素是出栈元素向后找第一个比其小的元素

    当元素出栈后,说明新栈顶元素是出栈元素向前找第一个比其小的元素

画图理解

在这里插入图片描述

思路

  • 对于一个高度,如果能得到向左向右的边界
  • 那么就能对每个高度求依次面积
  • 遍历左所有高度,即可得出最大面积
  • 使用单调栈,在出栈操作时得到前后边界并计算面积
    public int largestRectangleArea(int[] heights) {
        int res = 0;
        ArrayDeque<Integer> stack = new ArrayDeque<>();
        int[] newHeight = new int[heights.length + 2];
        //给数组前后加零 , 以便数组后面完整的弹出栈中
        for (int i = 1; i < heights.length + 1; i++) {
            newHeight[i] = heights[i - 1];
        }
        
        for (int i = 0; i < newHeight.length; i++) {
            //当栈为空,或者 当前栈顶的元素小于 后一个数组的元素
            while (!stack.isEmpty() && newHeight[(int) stack.peek()] > newHeight[i]) {
                //弹出栈顶的元素
                int cur = stack.pop();
                //前一个的元素位置
                int l = stack.peek();
                //后一个的位置
                int r = i;
                //计算大小
                res = Math.max(res, (r - l - 1) * newHeight[cur]);
            }
            stack.push(i);
        }
        return res;
    }
  • 单调栈学习建议):「力扣」第 42、739、496、316、901、402、581 题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值