前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >☆打卡算法☆LeetCode 84、柱状图中最大的矩形 算法解析

☆打卡算法☆LeetCode 84、柱状图中最大的矩形 算法解析

作者头像
恬静的小魔龙
发布2022-08-07 10:17:42
2500
发布2022-08-07 10:17:42
举报
文章被收录于专栏:Unity3DUnity3D
大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。

一、题目

1、算法题目

“给定n个非负整数,用来表示柱状图每个柱子的高度,求柱状图中最大的矩形的面积。”

题目链接:

来源:力扣(LeetCode)

链接:84. 柱状图中最大的矩形 - 力扣(LeetCode) (leetcode-cn.com)

2、题目描述

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

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

image.png
image.png
代码语言:javascript
复制
示例 1:
输入: heights = [2,1,5,6,2,3]
输出: 10
解释: 最大的矩形为图中红色区域,面积为 10
代码语言:javascript
复制
示例 2:
输入: heights = [2,4]
输出: 4

二、解题

1、思路分析

这道题与42题【接雨水】类似,42题是求下雨之后能接多少雨水,这道题是求最大矩形,为什么总是把相似的题目拉出来讲呢,因为这类题都会有着相似的解题思路,可以复习之后再进行解答。

42题【接雨水】的解题方法主要有双指针、单调栈等,这道题也可以用单调栈来解题。

首先,来思考一下如何去求最大矩形,找到某一根柱子,将其固定为矩形的高度h,随后根据这根柱子向左右延伸,直到遇到高度小于h的柱子,这样就确定了矩形的左右边界,边界的宽度为w,面积为h * w。

但是在确定宽的时候要左右遍历,时间复杂度较高,所以这时候就可以使用单调栈去优化成一重遍历。

OK,首先说一下什么是单调栈,单调栈是一种很经典的数据结构,里面存放的数据都是有序的,可以分为单调递增站和单调递减栈,常用于解决最大区间、最大视野、最大矩形等。

以单调递增栈为例,如果新的元素比栈顶元素大,就入栈;如果比栈顶元素小,那么就将栈内元素弹出来,直到栈顶比新元素小。

这样的好处在于栈内的元素都是递增的,当元素出栈时,新元素是出栈元素后小的一个元素,这样就可以得到一个左右边界的高度,使用单调栈,在出栈操作时得到左右边界并计算面积。

2、代码实现

代码参考:

代码语言:javascript
复制
class Solution {
    public int largestRectangleArea(int[] heights) {
        int n = heights.length;
        int[] left = new int[n];
        int[] right = new int[n];
        
        Deque<Integer> mono_stack = new ArrayDeque<Integer>();
        for (int i = 0; i < n; ++i) {
            while (!mono_stack.isEmpty() &amp;&amp; heights[mono_stack.peek()] >= heights[i]) {
                mono_stack.pop();
            }
            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() &amp;&amp; heights[mono_stack.peek()] >= heights[i]) {
                mono_stack.pop();
            }
            right[i] = (mono_stack.isEmpty() ? n : mono_stack.peek());
            mono_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;
    }
}
image.png
image.png

3、时间复杂度

时间复杂度 : O(N)

空间复杂度: O(N)

三、总结

1、对于某一个柱子,高度确定,要求它的左右边界。

2、根据左右边界求出宽度,长乘宽就可以得到面积

3、根据单调栈,在出栈操作的时候得到坐标边界,求出最大面积

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目
    • 1、算法题目
      • 2、题目描述
      • 二、解题
        • 1、思路分析
          • 2、代码实现
            • 3、时间复杂度
            • 三、总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档