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

举报
恬静的小魔龙 发表于 2022/03/02 09:08:54 2022/03/02
【摘要】 推荐阅读CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客QQ群:1040082875大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。 一、题目 1、算法题目“给定n个非负整数,用来表示柱状图每个柱子的高度,求柱状图中最大的矩形的面积。”题目链接:来源:力扣(LeetCode)链接:84...

推荐阅读

大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。

一、题目

1、算法题目

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

题目链接:

来源:力扣(LeetCode)

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

2、题目描述

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

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

image.png

示例 1:
输入: heights = [2,1,5,6,2,3]
输出: 10
解释: 最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4

二、解题

1、思路分析

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

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

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

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

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

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

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

2、代码实现

代码参考:

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() && 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() && 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

3、时间复杂度

时间复杂度 : O(N)

空间复杂度: O(N)

三、总结

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

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

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。