剑指 Offer II 039. 直方图最大矩形面积

概要

单调栈,思考起来比较费劲。

题目

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

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

img

链接:https://leetcode.cn/problems/0ynMMM

思路

还是使用单调栈。你会发现,这几道题的核心,都是利用一个单调栈,之后在遍历数组时,让当前元素和栈顶元素做比较,一直保证栈顶元素是最大(或最小)。

解答这一道题的几个核心点如下:

  1. 以一个柱的高度为中心,向两边扩散找边界。找到比这个柱子矮的柱子,就是边界。这时就可以根据柱的高度和边界长度计算面积了。
  2. 用一个栈顶大于栈底的单调栈,来维护左边界。
    1. 如果遍历到的当前元素大于栈顶元素,则入栈。
    2. 如果遍历到的当前元素小于栈顶元素,则栈顶元素则为柱,而当前元素的位置,就是最右端的边界。而因为是单调栈,所以栈顶下面的元素,则是栈顶为柱时,最右端的边界。
    3. 将栈顶出栈,比较新的栈顶和当前元素的大小关系,重复前两条的逻辑
  3. 遍历完毕,再将栈中还存在的元素,做进一步计算。只有最右边的柱高于前面的柱时,才会出现这种情况。因此此时的右边界,就是数组的右边界。

解法:单调栈

代码

public int largestRectangleArea(int[] heights) {
    Deque<Integer> stack = new ArrayDeque<>();
    // 方便处理边界问题
    stack.push(-1);
    int result = 0;
    for (int i = 0; i < heights.length; i++) {
        int current = heights[i];
        while (stack.peek() != -1 && heights[stack.peek()] > current) {
            // 获取栈顶元素下标的同时移除了栈顶元素
            int height = heights[stack.pop()];
            int with = i - stack.peek() - 1;
            result = Math.max(result, height * with);
        }
        stack.push(i);
    }
    // 处理栈中剩余的边界。此时右边界必然是数组的最右端
    while (stack.peek()!=-1) {
        result = Math.max(result, heights[stack.pop()] * (heights.length - stack.peek() - 1));
    }
    return result;
}

提交结果

img

P.S.这个题解的动画很棒:https://leetcode.cn/problems/0ynMMM/solution/hua-luo-yue-que-wo-zhen-de-zhen-de-nu-li-ohjt/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白码上飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值