剑指Offer专项突破版(39)—— 直方图最大矩形面积(正确性证明)

题目

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rVDQzBX1-1668849162270)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c9be167100d34925bb37c2ac3e1f00a8~tplv-k3u1fbpfcp-zoom-1.image)]

思路

根据官方题解,这道题的思路为:

分别以每个柱子为高,往左右延伸,看能延伸多远,作为宽,将高 * 宽记为area

当所有柱子都计算完后,返回最大的那个area

然后用单调栈优化,快速找到左右两边最近比当前柱子小的是哪个

但问题是:为什么这样做是对的?

首先需要明确:所有可能成为最大矩形的矩形,其高一定等于这个矩形覆盖的柱子中,最矮的那个

为什么?用反证法

  • 假设比最矮的那个还矮,那必然不是最大的矩形,因为高度可以更高
  • 假设比最矮的那个更高,这不可能

那我们可以遍历每一个柱子,计算以当前柱子为最矮的情况下(即高度为当前柱子),宽度能有多宽

因为最大的那个矩形,其高度必然等于其中一个柱子

我们将以每个柱子为高,的最大面积都计算出来了,因此答案必在其中!

代码

代码其实没太多好讲的,标准的单调栈做法:


 public int largestRectangleArea(int[] heights) {
    Stack<Integer> stack = new Stack<>();
    stack.push(-1);
    int maxArea = 0;
    for (int i = 0;i< heights.length;i++) {
        while (stack.peek() != -1 && heights[i] < heights[stack.peek()]) {
            int height = heights[stack.peek()];
            stack.pop();
            int width = i - stack.peek() - 1;
            maxArea = Math.max(maxArea, height * width);
        }
        stack.push(i);
    }
    
    while (stack.peek() != -1) {
        int height = heights[stack.peek()];
        stack.pop();
        int width = heights.length - stack.peek() - 1;
        maxArea = Math.max(maxArea, height * width);
    }
    
    return maxArea;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值