【LeetCode热题100】打卡第25天:柱状图中最大的矩形

news2024/12/28 4:12:58

文章目录

  • 柱状图中最大的矩形
    • ⛅前言
    • 🔒题目
    • 🔑题解

柱状图中最大的矩形

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

LeetCode热题100专栏🚀:LeetCode热题100

Gitee地址📁:知识汲取者 (aghp) - Gitee.com

题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

🔒题目

原题链接:84. 柱状图中最大的矩形

image-20230619180445622

🔑题解

  • 解法一:暴力枚举(中心扩散算法)

    暴力枚举的思路比较简单,每次枚举一个柱子,以这个柱子为中心,并且以当前这个柱子为最短板,向左右两边扩散,如果遇到小于当前柱子高度的柱子,则停止扩散,因为要确保中心的柱子是最短版,这样做就能保障每一个柱子都能得到一个最大矩形面积,而我们最终的结果就包含在这每一个柱子求出来的最大矩形面积,因此我们还需要使用一个变量来更新迭代得到最终的结果(●ˇ∀ˇ●)

    我们现在对上面的话进行一个精简,总结起来就是如下几步:

    • Step1:枚举每一个柱子
    • Step2:中心扩散。选定我们枚举的柱子,以它为中心往左右扩散,保障中心的柱子是最短的
    • Step3:计算并迭代最大矩形面积。每次枚举一个柱子都能得到以该柱子为中心的最大矩形的面积,同时比较当前的最大矩形面积,如果比当前最大矩形面积还大,就更新最大面积;如果更小,就保留原有的最大矩形面积

    但是这题是困难题,一般暴力枚举是很难通过的,所以这里也就只是提供一个思路,锻炼一下逻辑思维

    PS:关于中心扩散算法还可以看【打卡第5天:5.最长回文子串】

    示例1数据的图解:

    image-20230619182021079

    /**
     * @author ghp
     * @title
     */
    class Solution {
        public int largestRectangleArea(int[] heights) {
            // 遍历每一个柱子
            int ans = 0;
            for (int i = 0; i < heights.length; i++) {
                // 往左遍历
                int l = i;
                while (l > 0 && heights[l - 1] >= heights[i]) {
                    l--;
                }
                // 往右遍历
                int r = i;
                while (r < heights.length - 1 && heights[r + 1] >= heights[i]) {
                    r++;
                }
                // 计算当前柱子能形成矩形的最大面积
                int width = r - l + 1;
                // 更新矩形的最大面积
                ans = Math.max(ans, width * heights[i]);
            }
            return ans;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为数组中元素的个数

  • 解法二:单调栈

    这题考的基础模型其实就是:在一维数组中对每一个数找到第一个比自己小的元素。这类“在一维数组中找第一个满足某种条件的数”的场景就是典型的单调栈应用场景。——摘自LeetCode上一位大佬的评论

    什么是单调栈?单调栈(Monotonic Stack)是一种特殊的栈数据结构,用于解决一类相关的问题,例如寻找下一个更大元素或者下一个更小元素等。单调栈的特点是栈中维持的元素满足某种单调性,可以是递增也可以是递减(本题是递增单调栈)。

    单调栈的主要思路:使用一个栈,从左往右记录每一个柱子,当发现当前柱子比上一个柱子要矮,就计算上一个柱子能够得到的最大矩形的面积,为什么可以这样呢?因为当发现当前柱子比上一个柱子要矮时,说明上一个柱子的高度被限制了,上一个柱子能够组成的最大矩形的面积可以由当前这个较矮的柱子组成,这里画个图加以理解:

    image-20230619190537934

    这样通过层层的迭代,就可以得到这一连串柱子能够组成矩形的最大面积了(●’◡’●),而这个栈是一个递增的栈,栈中的柱子是递增的,发现矮的柱子就需要出栈,直到栈重新是递增的为止。

    上面的话,总结起来就下面几步:

    • Step1:从左往右枚举柱子。
    • Step2:寻找比先入栈柱子的较矮柱子。发现较矮柱子,就可以计算最先入栈柱子的最大矩形面积,因为栈中的柱子的连续递增的,所以矩形的高是最先入栈的柱子,宽是当前柱子的索引减去最先入栈柱子的索引
    • Step3:计算最大矩形面积,通过Step1和Step2可以计算出每一个柱子可以构成的最大矩形的面积,然后通过迭代更新,得出最终的结果

    单调栈的思路很容易理解,但是实现起来感觉挺麻烦的,有很多需要注意的地方,比如:我们需要在栈的第一个元素和最后一个元素,添加一个0,用于最后的强制出栈,这一步是十分关键的,一般也很难想到,需要有一定的做题经验(大佬除外),所以说这一道困难题还是很有水准的 O(∩_∩)O

    import java.util.ArrayDeque;
    import java.util.Arrays;
    import java.util.Deque;
    
    /**
     * @author ghp
     * @title
     */
    class Solution {
        public int largestRectangleArea(int[] heights) {
            int res = 0;
            Deque<Integer> stack = new ArrayDeque<>();
            int[] new_heights = new int[heights.length + 2];
            for (int i = 1; i < heights.length + 1; i++) new_heights[i] = heights[i - 1];
            System.out.println(Arrays.toString(new_heights));
            for (int i = 0; i < new_heights.length; i++) {
    //            System.out.println("------------------------");
    //            System.out.println("栈弹出前:"+stack.toString());
                while (!stack.isEmpty() && new_heights[stack.peek()] > new_heights[i]) {
                    int cur = stack.pop();
    //                System.out.println("栈弹出后:"+stack.toString());
    //                System.out.println("面积为:"+(i - stack.peek() - 1) * new_heights[cur]);
                    res = Math.max(res, (i - stack.peek() - 1) * new_heights[cur]);
                }
                stack.push(i);
            }
            return res;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)

    其中 n n n 为数组中元素的个数


参考题解:

  • 暴力解法、栈(单调栈、哨兵技巧) - 柱状图中最大的矩形 - 力扣(LeetCode)

在此致谢各位大佬 (^^ゞ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/663568.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GEE:绘制一个点的Landsat1985-2020年逐日NDVI时间序列折线图

作者:CSDN @ _养乐多_ 本文记录了在GoogleEarthEngine(GEE)平台上选择一个点,根据该点在时间段内所有有效像素值绘制折线图的代码。 结果如下图所示, 文章目录 一、代码二、代码链接一、代码 var roi = geometry Map.addLayer(roi, {color

6.15集合1 和 泛型

举例 1&#xff1a;中药店&#xff0c;每个抽屉外面贴着标签 举例 2&#xff1a;超市购物架上很多瓶子&#xff0c;每个瓶子装的是什么&#xff0c;有标签 举例 3&#xff1a;家庭厨房中 集合 我们接下来要学习的内容是Java基础中一个很重要的部分&#xff1a;集合 1 Coll…

【服务器数据恢复】AIX下raid故障导致pool无法加载的数据恢复案例

服务器数据恢复环境&#xff1a; IBM P740小型机AIX操作系统Sybase数据库V7000存储。V7000存储配置了12块SAS机械硬盘&#xff08;其中一块为热备盘&#xff09;组建一组raid5磁盘阵列。存储设备一共创建了2组Mdisk&#xff0c;加到一个pool中。 服务器故障&#xff1a; IBM V…

网络管理与维护(三)网络安全

网络安全 网络安全威胁 非授权访问 信息泄漏 破坏数据完整性 拒绝服务攻击 利用网络传播病毒 安全服务和安全机制 总结 1.通常可以把网络信息安全的问题划分为物理层、网络层、数据层和内容层四个层面。 2.网络存在的威胁主要表现&#xff1a; 非授权访问、信息泄漏、破坏数…

基于Django+Vue开发的社区疫情管理系统(附源码)

基于Django、Django Rest framework、Vue的前后端分离的社区疫情管理系统。 一、系统功能 用户管理&#xff08;只有管理员有权限&#xff09; 用户注册用户登录修改用户信息删除用户修改密码权限管理 首页数据展示 国内疫情数据展示国内疫情新闻近30日的感染人数&#xff08;…

【论文阅读】Adap-t: Adaptively Modulating Embedding Magnitude for Recommendation

【论文阅读】Adap-&#x1d70f;: Adaptively Modulating Embedding Magnitude for Recommendation 文章目录 【论文阅读】Adap-&#x1d70f;: Adaptively Modulating Embedding Magnitude for Recommendation1. 来源2. 介绍3. 模型解读3.1 准备工作3.1.1 任务说明3.1.2 基于嵌…

Linux:http服务(Apache 2.4.57)源码编译——配置网站 || 入门到入土

目录 1.下载源码包 2.配置httpd运行环境 3.编译源码包安装apache软件 4.优化执行路径 5.添加httpd系统服务 正文 1.httpd服务器的基本配置 2.本章持续更新 我的服务器为centos7系统 1.下载源码包 访问官方网站↓↓↓ Welcome! - The Apache HTTP Server Project ↑↑…

ONLYOFFICE Docs 7.4 版本大大增强了图形编辑功能!

ONLYOFFICE Docs 7.4 版本大大增强了图形编辑功能&#xff01; 书接上文&#xff1a; 北冰洋汽水我的最爱https://mp.weixin.qq.com/s?__bizMzI2MjUyNzkyNw&mid2247493734&idx1&sn416c4ee5756ea59883591d3c2c4a6ae4&chksmea4b66bedd3cefa89050e25b661e0be16…

malloc 背后的虚拟内存 和 malloc实现原理

面试的时候经常会被问到 malloc 的实现。从操作系统层面来说&#xff0c;malloc 确实是考察面试者对操作系统底层的存储管理理解的一个很好的方式&#xff0c;涉及到虚拟内存、分页/分段等。下面逐个细说。 1. 虚拟内存 首先需要知道的是程序运行起来的话需要被加载的物理内存…

spark 和 flink 的对比

一、设计理念 Spark 的数据模型是 弹性分布式数据集 RDD(Resilient Distributed Dattsets)&#xff0c;这个内存数据结构使得spark可以通过固定内存做大批量计算。初期的 Spark Streaming 是通过将数据流转成批 (micro-batches)&#xff0c;即收集一段时间(time-window)内到达的…

【计算机组成原理】——知识点复习(期末不挂科版)

课本&#xff1a; 考试题型&#xff1a; 题型一、计算题&#xff08;30分&#xff09; 1、定点数表示&#xff1a;用原码、反码、补码、移码表示十进制数&#xff08;5分&#xff09; 2、浮点数表示&#xff1a;十进制数↔单精度浮点数&#xff08;5分&#xff09; 3、加减运…

行业报告 | AI+制造业赋能,机器视觉开启掘金新大陆(上)

原创 | 文 BFT机器人 01 核心要点 Al制造业赋能&#xff0c;META 发布 SAM 助力机器视觉迎来 GPT 时刻。 机器视觉技术使得工业设备能够“看到”它正在进行的操作并进行快速决策&#xff0c;完整机器视觉系统由硬件软件组成,分别进行成像和图像处理工作。 目前&#xff0c;以“…

全网超全,接口自动化测试实战总结详全,这几个阶段你知道吗?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口自动化根本目…

【深入浅出 Spring Security(十)】权限管理的概述和使用详情

权限管理 一、授权的核心概念二、权限管理策略权限表达式&#xff08;SpEL Spring EL&#xff09;1. 基于 URL 的权限管理&#xff08;过滤器&#xff09;基本用法 2. 基于 方法 的权限管理&#xff08;AOP&#xff09;EnableGlobalMethodSecurity基本用法 三、权限管理之版本问…

游戏中用脚开飞机实现方案

看看这个图片&#xff0c;有人用脚开飞机&#xff0c;用几个踏板去控制&#xff0c;在游戏中&#xff0c;开飞机的操作比较简单&#xff0c;上升&#xff0c;下降&#xff0c;加减油门&#xff0c;方向左&#xff0c;方向右。 android设备中&#xff0c;使用模拟点击就可以实现…

好用的电容笔有哪些推荐?apple pencil的平替笔测评

随着平板电脑在校园、办公室中的应用越来越广泛&#xff0c;需要一种具有良好性能的电容笔。苹果品牌原装的这支电容笔&#xff0c;虽然功能很强&#xff0c;但因为其的价格实在是太贵了&#xff0c;所以只是用来学习记笔记&#xff0c;实在是太浪费了。所以&#xff0c;哪个电…

python接口自动化(一)--什么是接口、接口优势、类型(详解)

简介 经常听别人说接口测试&#xff0c;接口测试自动化&#xff0c;但是你对接口&#xff0c;有多少了解和认识&#xff0c;知道什么是接口吗&#xff1f;它是用来做什么的&#xff0c;测试时候要注意什么&#xff1f;坦白的说&#xff0c;笔者之前也不是很清楚。接下来先看一下…

计算机网络——自顶向下方法(第一章学习记录)

什么是Internet? 可以从两个不同的方面来理解Internet。&#xff08;它的构成。它的服务&#xff09; 1.因特网的主要构成 处在因特网的边缘部分就是在因特网上的所有主机&#xff0c;这些主机又称为端系统&#xff08;end system&#xff09;&#xff0c;端系统通过因特网服…

openEuler+Linaro合作成果展示|2023开放原子全球开源峰会

2023年6月11&#xff5e;13日&#xff0c;2023年开放原子全球开源峰会&#xff08;OpenAtom&#xff09;在北京经济开发区北人亦创国际会展中心召开&#xff0c;本届峰会旨在搭建全球开源生态发展合作交流平台&#xff0c;聚焦开源生态建设发展&#xff0c;并组织了openEuler、…

STL容器——unordered_set的用法

0、概述 unordered_set容器&#xff0c;可直译为无序 set 容器。即 unordered_set容器和 set 容器很像&#xff0c;唯一的区别就在于 set容器会自行对存储的数据进行排序&#xff0c;而 unordered_set 容器不会。下面是set、multiset和unordered_set之间的差别。 注意这三种集…