DAY60 84.柱状图中最大的矩形

84.柱状图中最大的矩形

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

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

思路 

单调栈

本地单调栈的解法和接雨水的题目是遥相呼应的。

为什么这么说呢,42. 接雨水 (opens new window)是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。

这里就涉及到了单调栈很重要的性质,就是单调栈里的顺序,是从小到大还是从大到小

在题解42. 接雨水 (opens new window)中我讲解了接雨水的单调栈从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。

那么因为本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!

我来举一个例子,如图:

只有栈里从大到小的顺序,才能保证栈顶元素找到左右两边第一个小于栈顶元素的柱子。

所以本题单调栈的顺序正好与接雨水反过来。

此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度

理解这一点,对单调栈就掌握的比较到位了。

除了栈内元素顺序和接雨水不同,剩下的逻辑就都差不多了,在题解42. 接雨水 (opens new window)我已经对单调栈的各个方面做了详细讲解,这里就不赘述了。

主要就是分析清楚如下三种情况:

  • 情况一:当前遍历的元素heights[i]大于栈顶元素heights[st.top()]的情况
  • 情况二:当前遍历的元素heights[i]等于栈顶元素heights[st.top()]的情况
  • 情况三:当前遍历的元素heights[i]小于栈顶元素heights[st.top()]的情况

每一次入栈新元素时,我是一直向左边比较比我小的柱子,计算面积并且更新result的。这个思路好神奇我还是没有太想明白中间在while中一直在pop是怎么继续比较的。我个人认为一直在计算的是以每一个i为结尾(right)能够组成的最大矩形长度,这样理解就对了。因为如果当前的i对应的值是2,之前有5,6。即便2之后在出现6,由于2存在的原因也无法组成以5、6为高度的矩形了,所以2能够pop掉2之前所有比2大的st.top()。

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int result = 0;stack<int> st;heights.insert(heights.begin(), 0);heights.push_back(0);st.push(0);for (int i = 1; i < heights.size(); ++i) {if (heights[i] > heights[st.top()]) {st.push(i);} else if (heights[i] == heights[st.top()]) {st.pop();st.push(i);} else if (heights[i] < heights[st.top()]) {while (!st.empty() && heights[i] < heights[st.top()]) {int mid = st.top();st.pop();if (!st.empty()) {int left = st.top();int right = i;int w = right - left - 1;int h = heights[mid];result = max(result, w * h);cout << mid << ' ' << left << ' ' << right << ' ' << w << ' ' << h << ' ' << result << endl;}}st.push(i);}}return result;}
};

细心的录友会发现,我在 height数组上后,都加了一个元素0, 为什么这么做呢?

首先来说末尾为什么要加元素0?

如果数组本身就是升序的,例如[2,4,6,8],那么入栈之后 都是单调递减,一直都没有走 情况三 计算结果的哪一步,所以最后输出的就是0了。 如图:

那么结尾加一个0,就会让栈里的所有元素,走到情况三的逻辑。

开头为什么要加元素0?

如果数组本身是降序的,例如 [8,6,4,2],在 8 入栈后,6 开始与8 进行比较,此时我们得到 mid(8),rigt(6),但是得不到 left。

(mid、left,right 都是对应版本一里的逻辑)

因为 将 8 弹出之后,栈里没有元素了,那么为了避免空栈取值,直接跳过了计算结果的逻辑。

之后又将6 加入栈(此时8已经弹出了),然后 就是 4 与 栈口元素 8 进行比较,周而复始,那么计算的最后结果resutl就是0。 如图所示:

所以我们需要在 height数组前后各加一个元素0。

结束啦,今天就是算法训练营的Day60!

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

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

相关文章

git -1

1.创建第一个仓库并配置local用户信息 git config git config --global 对当前用户所有仓库有效 git config --system 对系统所有登录的用户有效 git config --local 只对某个仓库有效 git config --list 显示配置 git config --list --global 所有仓库 git config --list…

微信小程序 prettier 格式化

一、安装prettier插件 二、打开设置 然后再打开setting.json 新增代码 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml", "**/*.wx…

基于 Glibc 版本升级的 DolphinDB 数据查询性能优化实践

在高并发查询、查询需要涉及很多个分区的情况下&#xff0c;低版本的 glibc&#xff08;低于2.23&#xff09;会严重影响查询性能。需要升级 glibc 解决该问题优化性能。我们撰写了本文&#xff0c;通过 patchelf 工具修改可执行文件和动态库的 rpath&#xff0c;达到无需升级系…

专业课140+总分420+东南大学920专业综合考研,信息学院通信专业考研分享

专业课140总分420东南大学920专业综合考研&#xff0c;信息学院通信专业考研分享 我是三月开始系统考研备战&#xff0c;寒假先看的高数全书&#xff0c;奈何在家效率极其低下&#xff0c;才草草看了前三四章。回校后学习的比较认真&#xff0c;每天大概保持10个小时左右&…

3分钟看完NVIDIA GPU架构及演进

近期随着 AI 市场的爆发式增长&#xff0c;作为 AI 背后技术的核心之一 GPU&#xff08;图形处理器&#xff09;的价格也水涨船高。GPU 在人工智能中发挥着巨大的重要&#xff0c;特别是在计算和数据处理方面。目前生产 GPU 主流厂商其实并不多&#xff0c;主要就是 NVIDIA、AM…

利用OpenCV实现图片中导线的识别

下面是一个需求&#xff0c;识别图片中的导线&#xff0c;要在图像中检测导线&#xff0c;我们需要采用不同于直线检测的方法。由于OpenCV没有直接的曲线检测函数&#xff0c;如同它对直线提供的HoughLines或HoughLinesP&#xff0c;检测曲线通常需要更多的图像处理步骤和算法&…

java io流中为什么使用缓冲流就能加快文件读写速度

FileInputStream的read方法底层确实是通过调用JDK层面的read方法&#xff0c;并且这个JDK层面的read方法底层是使用C语言编写的&#xff0c;以实现高效的文件读取功能。但是它会涉及多次内核态与操作系统交互。当我们使用FileInputStream的read方法读取文件时&#xff0c;首先会…

UEC++ day7

敌人NPC机制 敌人机制分析与需求 新建一个character类来作为敌人&#xff0c;直接建蓝图设置骨骼网格&#xff0c;因为敌人可能多种就不规定死&#xff0c;然后这个敌人肯定需要两个触发器&#xff0c;一个用于大范围巡逻&#xff0c;一个用于是否达到主角近点进行攻击 注意我…

【Flink】Process Function

目录 1、ProcessFunction解析 1.1 抽象方法.processElement() 1.2 非抽象方法.onTimer() 2、Flink中8个不同的处理函数 2.1 ProcessFunction 2.2 KeyedProcessFunction 2.3 ProcessWindowFunction 2.4 ProcessAllWindowFunction 2.5 CoProcessFunction 2.6 ProcessJo…

https和http的区别和优势

大家好&#xff0c;我是咕噜-凯撒&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;和HTTPS&#xff08;安全超文本传输协议&#xff09;是用于在网络上传输数据的协议&#xff0c;HTTPS相比HTTP在数据传输过程中更加安全可靠&#xff0c;适合对数据安全性要求较高的场景…

ventoy安装操作系统

下载ventoy https://github.com/ventoy/Ventoy/releases/download/v1.0.96/ventoy-1.0.96-windows.zip 解压后执行 Ventoy2Disk 2、安装后将ISO放入U盘大的分区&#xff0c;通过U盘启动就可以识别到ISO镜像开始装系统

MySQL 日志管理、备份与恢复

一、MySQL 日志管理 MySQL 的日志默认保存位置为 /usr/local/mysql/data vim /etc/my.cnf [mysqld] ##错误日志&#xff0c;用来记录当MySQL启动、停止或运行时发生的错误信息&#xff0c;默认已开启 log-error/usr/local/mysql/data/mysql_error.log #指定日志的保存位置…

springboot项目基于jdk17、分布式事务seata-server-1.7.1、分库分表shardingSphere5.2.1开发过程中出现的问题

由于项目需要&#xff0c;springboot项目需基于jdk17环境开发&#xff0c;结合nacos2.0.3、分布式事务seata-server-1.7.1、分库分表shardingSphere5.2.1等&#xff0c;项目启动过程中出现的问题解决方式小结。 问题一&#xff1a; Caused by: java.lang.RuntimeException: j…

职场Excel:求和家族,不简单

说到excel函数&#xff0c;很多人第一时间想到的就是求和函数sum。作为excel入门级函数&#xff0c;sum的确是小白级的&#xff0c;以至于很多人对求和函数有点“误解”&#xff0c;觉得求和函数太简单了。 但是&#xff0c;你可能不知道&#xff0c;sum只是excel求和家族里的一…

Ubuntu22.04 交叉编译GCC13.2.0 for Rv1126

一、安装Ubuntu22.04 sudo apt install vim net-tools openssh-server 二、安装必要项 sudo apt update sudo apt upgrade sudo apt install build-essential gawk git texinfo bison flex 三、下载必备软件包 1.glibc https://ftp.gnu.org/gnu/glibc/glibc-2.38.tar.gz…

引迈-JNPF低代码项目技术栈介绍

从 2014 开始研发低代码前端渲染&#xff0c;到 2018 年开始研发后端低代码数据模型&#xff0c;发布了JNPF开发平台。 谨以此文针对 JNPF-JAVA-Cloud微服务 进行相关技术栈展示&#xff1a; 1. 项目前后端分离 前端采用Vue.js&#xff0c;这是一种流行的前端JavaScript框架&a…

4D毫米波雷达和3D雷达、激光雷达全面对比

众所周知&#xff0c;传统3D毫米波雷达存在如下性能缺陷&#xff1a; 1&#xff09;静止目标和地物杂波混在一起&#xff0c;难以区分&#xff1b; 2) 横穿车辆和行人多普勒为零或很低&#xff0c;难以检测&#xff1b; 3) 高处物体和地面目标不能区分&#xff0c;容易造成误刹…

从CNN到Transformer:基于PyTorch的遥感影像、无人机影像的地物分类、目标检测、语义分割和点云分类

我国高分辨率对地观测系统重大专项已全面启动&#xff0c;高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成&#xff0c;将成为保障国家安全的基础性和战略性资源。随着小卫星星座的普及&#xff0c;对地观测已具备多次以上的全球覆盖…