每日一题——柱状图中最大的矩形
柱状图中最大的矩形
题目链接
用什么数据结构?
要得到柱状图中最大的矩形,我们就必须要知道对于每一个高度heights[i]
,他所能勾勒出的矩形最大是多少(即宽度最大是多少)。
而对应到图上我们可以知道,要知道最大宽度,那就需要通过对下标的计算得到,因此要存储的也应该是每个高度对应的下标。
即:通过存储的下标索引找到对应的高度,同时快速计算出宽度,最终得到面积
我们就拿上面的例子进行分析:
- 一开始遍历的柱形高度是2,但以这一高度所确定的矩形还不能确定其面积的最大值,因此继续遍历
- 第二个柱形高度为1,此时这一高度所确定的最大矩形还不能确定。但是它前面的下标为0的柱形所确定的最大矩形就可以确定了。因为下标为1的这个柱形高度比下标为0的小,矮的卡在了高的后面,那么这个高的就不能向右扩展了。
- 这个时候,我们也就能计算下标为0的这一高度所能确定的最大矩形的面积了。同时,既然这一下标的高度已经确定,我们也就可以忽略这一下标代表的高度了,我们将其标灰。
-
第三个高度为5,由同样的分析可得,下标为2和下标为1的高度都不能确定其最大的矩形。继续遍历。
-
第四个高度为6,同样,高度为
1,5,6
的三个柱形也同样不能确定最大的矩形,继续便利。 -
第五个高度为2,小于下标为3的高度,因此下标为3高度为6的柱形确定的最大矩形就知道了。面积
size = 6 * (4-2-1) = 6
,同时由于这个柱形已经计算,就将其忽略、标灰。-
下标为4高度为2的柱形仍低于下标为2高度为5的柱形,因此下标为2高度为5的柱形确定的最大矩形也就知道了。面积
size = 5 * (4-1-1) = 10
,同时将这一柱形忽略、标灰。 -
下标为4高度为2的柱形高于下标为1高度为1的柱形,因此这两个柱形仍不能确定其最大的矩形,继续遍历。
-
-
第六个的高度为3,由同样的分析,高度为
1,2,3
的柱形都不能确定其最大的矩形
此时我们就遍历完了整个heights
数组,但是我们还有三个高度的最大矩形还没有确定,为了处理这三个数据,我们可以假设下标为6的柱形的高度为0(小于1都可以)
- 这样,下标为5高度为3的柱形就被夹在了两个较矮柱形的中间,其最大矩形也就确定了。
size = 3 * (6-4-1) = 3
- 同理,下标为4高度为2的矩形面积为:
size = 2 * (6-1-1) = 8
- 此时,只剩下下标为1高度为1的柱形,他是所有柱形中最低的柱形,所以它最大矩形的宽度就是整个数组的长度,因此面积
size = 1 * 6 = 6
至此,每个柱形所确定的最大矩形都已经分析完毕。
由上面的分析我们可以得出以下结论:
- 存储下标时,我们是从左到右存储的,但是计算下标对应的高度所确定的矩形面积时,是从右向左计算的(例如是先计算高度为6的面积在计算高度为5的面积),这符合先入后出的特性,因此这一题我们要用到的数据结构是栈。
- 之所以能确定一个柱形的最大矩形,就是在他右边碰到了比他更低的柱形(因为这个更低的柱形限制了这个高柱形的扩张)。因此这个栈存放的下标对应的高度应该是单调非递减的(注意不是单调递增),只要碰到递减的情况,就说明可以计算栈顶元素所代表高度的矩形面积了。
- 这个栈之所以要单调非递减时要考虑到进栈元素等于栈顶元素的情况。如下图:
- 如果将栈设计为单调递增的,那么当进栈元素5入栈时,栈顶元素5就要出栈,并计算其面积,但问题是这个进栈元素5并不小于这个栈顶元素5,那么这个栈顶元素5所确定的最大矩形也就不能确定。
- 因此进栈元素等于栈顶元素时,栈顶元素不要出栈。即这个栈为单调非递减的。
考虑特殊情况(添加哨兵位)
- 情况一:计算宽度时栈空。如下图:
此时,栈中存储的下标为[0]
,进栈下标对应的高度小于栈顶元素对应的高度,栈顶元素需要出栈,并计算其高度对应的最大矩形。现在问题来了,栈顶元素出栈后栈为空,没有下标用来计算宽度,这里就要用if(stackEmpty)
来进行特殊处理,但显然这是不方便的。因此我们可以在heights
数组的最前面加入一个高度0
,这样我们就可以保证栈中始终留有数据(这个0不可能出栈),也就可以更加方便的计算宽度了。
- 情况二:遍历完
heights
数组后,栈中还留有有效数据(部分柱形的最大矩形还未确定),如下图:
要计算出每个柱形的最大矩形,也就是要将栈中的每个下标都出栈,而要确保每个下标都可以出栈,那就要保证进栈下标代表的高度要小于栈中元素对应的高度,因此我们可以在heights
数组的末尾再加上一个0
,这样就可以保证在遍历完heights
数组的同时,每个高度的最大矩形都可以被计算了。
这两个高度为0,站在数组两边的柱形,就是我们常说的哨兵
实现代码
int largestRectangleArea(int* heights, int heightsSize){//添加哨兵位:heights = (int*)realloc(heights, sizeof(int) * (heightsSize + 2));heights[heightsSize + 1] = 0; //尾部添加0for (int i = heightsSize; i > 0; i--)heights[i] = heights[i - 1];heights[0] = 0; //头部添加0int *stack = (int*)malloc(sizeof(int) * (heightsSize + 2));int top = 0;int ret_size = 0;for (int i = 0; i < heightsSize + 2; i++){//当栈不为空并且进栈元素小于栈顶元素//就开始计算矩形面积while (top != 0 && heights[i] < heights[stack[top - 1]]){//栈顶元素出栈int high_index = stack[top - 1];top--;int wide = i - stack[top - 1] - 1; //宽度int high = heights[high_index]; //高度ret_size = ret_size > wide * high ? ret_size : wide * high;}//计算完成后或者没有进入循环,进栈元素都要入栈stack[top++] = i;}free(stack); //释放栈return ret_size;
}
相关文章:

每日一题——柱状图中最大的矩形
柱状图中最大的矩形 题目链接 用什么数据结构? 要得到柱状图中最大的矩形,我们就必须要知道对于每一个高度heights[i],他所能勾勒出的矩形最大是多少(即宽度最大是多少)。 而对应到图上我们可以知道,要知…...

Banana Pi推出基于龙芯2K1000LA处理器的信创工业控制开发平台
Banana Pi推出基于龙芯2K1000LA处理器的信创工业控制开发平台:BPI-5202信创工业控制开发平台 BPI-5202 龙芯2K1000LA 信创工业控制开发平台 1.1 工控机的应用场景 物联网的狂潮,既是一场众多的计算机软硬件厂家(也包括通讯方案和产品厂家&…...

springCloud整合Zookeeper的时候调用找不到服务
SpringCloud整合Zookeeper的时候调用找不到服务 首先,我们在注册中心注册了这个服务: 然后我们使用RestTemplate 调用的时候发现失败了:找不到这个服务: 找了很多资料发现这个必须要加上负载才行 BeanLoadBalanced //负载publi…...

【kubernetes】使用kubepshere部署中间件服务
KubeSphere部署中间件服务 入门使用KubeSphere部署单机版MySQL、Redis、RabbitMQ 记录一下搭建过程 (内容学习于尚硅谷云原生课程) 环境准备 VMware虚拟机k8s集群,一主两从,master也作为工作节点;KubeSphere k8skubesphere devops比较占用磁…...
如何从tabbar页面传数据
无论是百度小程序还是微信小程序,app.json中规定的tabbar页面是不支持传参的,例如: <navigator url../service/service?typeid6 openType"switchTab"> 服务项目 </navigator> 上面的navigater跳转有个属性&#…...
软考高级系统架构设计师系列论文七十四:基于构件的软件开发
软考高级系统架构设计师系列论文七十四:基于构件的软件开发 一、构件相关知识点二、摘要三、正文四、总结一、构件相关知识点 软考高级系统架构设计师系列之:面向构件的软件设计,构件平台与典型架构...
图为科技_边缘计算在智能安防领域的作用
边缘计算在智能安防领域发挥着重要的作用。智能安防系统通常需要处理大量的图像、视频和传感器数据,并对其进行实时分析和处理。边缘计算可以将计算和数据处理功能移动到离数据源更接近的地方,例如摄像头、传感器设备或安防终端。 以下是边缘计算在智能…...

Android 13 - Media框架(7)- NuPlayer::Source
Source 在播放器中起着拉流(Streaming)和解复用(demux)的作用,Source 设计的好坏直接影响到播放器的基础功能,我们这一节将会了解 NuPlayer 中的通用 Source(GenericSource)关注本地…...

MySql015——使用子查询
一、创建customers表 ######################## # Create customers table ######################## use study;CREATE TABLE customers (cust_id int NOT NULL AUTO_INCREMENT,cust_name char(50) NOT NULL ,cust_address char(50) NULL ,cust_city char…...
leetcode 355 设计推特
用链表存储用户发送的每一个推特,用堆获取最先的10条动态 class Twitter {Map<Integer,Set<Integer>> followMap;//规定最新的放到最后Map<Integer,Tweet> postMap;//优先队列(堆)PriorityQueue<Tweet> priorityQueue;int time…...

倒数 2 周|期待 2023 Google开发者大会
9 月 6-7 日,中国上海 前沿科技,新知同享 趣味体验,灵感齐聚 技术生态,多元共进 关注官网最新信息,敬请期待大会开幕 2023 Google 开发者大会官网 相信你一定记得,在今年 5 月的 Google I/O 大会上&am…...
代码随想录day57
516最长回文子序列 class Solution { public:int longestPalindromeSubseq(string s) {vector<vector<int>>dp(s.size(),vector<int>(s.size(),0));for(int i0;i<s.size();i)dp[i][i]1;for(int is.size()-1;i>0;i--){for(int ji1;j<s.size();j){if…...

YOLOv5、v8改进:CrissCrossAttention注意力机制
目录 1.简介 2. yolov5添加方法: 2.1common.py构建CrissCrossAttention模块 2.2yolo.py中注册 CrissCrossAttention模块 2.3修改yaml文件。 1.简介 这是ICCV2019的用于语义分割的论文,可以说和CVPR2019的DANet遥相呼应。 和DANet一样,…...

RabbitMQ特性介绍和使用案例
❤ 作者主页:李奕赫揍小邰的博客 ❀ 个人介绍:大家好,我是李奕赫!( ̄▽ ̄)~* 🍊 记得点赞、收藏、评论⭐️⭐️⭐️ 📣 认真学习!!!🎉🎉 文章目录 RabbitMQ特性…...

Ansible 使用 RHEL 系统角色
安装 RHEL 系统角色软件包,并创建符合以下条件的 playbook /home/greg/ansible/timesync.yml 在所有受管节点上运行 使用 timesync 角色 配置该角色,以使用当前有效的 NTP 提供商 配置该角色,以使用时间服务器 172.25.254.254 配置该角色&am…...

重新认识Android中的线程
线程的几种创建方式 new Thread:可复写Thread#run方法。也可以传递Runnable对象,更加灵活。缺点:缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统的资源导致死机或oom。 new Thread(new…...

前端(十五)——GitHub开源一个react封装的图片预览组件
👵博主:小猫娃来啦 👵文章核心:GitHub开源一个react封装的图片预览组件 文章目录 组件开源代码下载地址运行效果展示实现思路使用思路和api实现的功能数据和入口部分代码展示 组件开源代码下载地址 Gitee:点此跳转下载…...

DELL Power Edge R740 安装 OracleLinux-R7-U9-Server
一、准备好 OracleLinux-R7-U9-Server-x86_64-dvd 安装介子: 二、通过 iDRAC挂dvd 安装介子 三、在 iDRAC 开机控制选择虚拟 CD/DCD/ISO 电源控制选择 复位系统(热启动) 四、进入安装阶段 五、配置时区 六、配置磁盘 七、删除之前的旧分区 …...

深入了解OpenStack:创建定制化QCOW2格式镜像的完全指南
OpenStack 创建自定义的QCOW2格式镜像 前言 建议虚机网络配置为 NAT 或 桥接,因为未来 KVM虚机 需要借助 虚机 的外网能力进行联网安装软件包 虚机在启动前,必须在 VMware Workstation 上为其开启虚拟化引擎 虚拟化 Intel VT-x/EPT 或 AMD-V 安装kvm …...

【Java 中级】一文精通 Spring MVC - 数据格式化器(六)
👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区&#x…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...