Day 63:单调栈 LeedCode 84.柱状图中最大的矩形

84. 柱状图中最大的矩形

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

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

示例 1:

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

示例 2:

输入: heights = [2,4]
输出: 4

提示:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

思路:

本题和接雨水有相似之处

Day62:单调栈 LeedCode503. 下一个更大元素 II 42. 接雨水-CSDN博客

1.暴力法:

最大面积的矩形的高,一定是某个柱子的高

求出以每根柱子的高为矩形的高的矩形的最大矩形面积

寻找当前柱子的左边和右边第一个小于其高度的柱子,这两个柱子之间的宽度为矩形的宽w,h为当前柱子的高,面积为w*h

代码参考:

class Solution {public int largestRectangleArea(int[] heights) {int sum=0;for(int i=0;i<heights.length;i++){int left=i;int right=i;for(;left>=0;left--){if(heights[left]<heights[i]){break;}}for(;right<heights.length;right++){if(heights[right]<heights[i]){break;}}sum=Math.max(sum,(right-left-1)*heights[i]);}return sum;}
}

暴力法时间超过限制

2.双指针法:

为了得到两边的比当前高度矮的柱子,使用了暴力法,每到一个柱子都向两边遍历一遍,这其实是有重复计算的。我们把每一个位置的左边第一个高度小于当前高度的位置记录在一个数组上( minLeftIndex),右边第一个高度小于当前高度的位置记录在一个数组上(minRightIndex),这样就避免了重复计算。利用空间换时间

class Solution {public int largestRectangleArea(int[] heights) {int length = heights.length;int[] minLeftIndex = new int [length];int[] minRightIndex = new int [length];// 记录左边第一个小于该柱子的下标minLeftIndex[0] = -1 ;for (int i = 1; i < length; i++) {int t = i - 1;// 这里不是用if,而是不断向右寻找的过程while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t];minLeftIndex[i] = t;}// 记录每个柱子右边第一个小于该柱子的下标minRightIndex[length - 1] = length;for (int i = length - 2; i >= 0; i--) {int t = i + 1;while(t < length && heights[t] >= heights[i]) t = minRightIndex[t];minRightIndex[i] = t;}// 求和int result = 0;for (int i = 0; i < length; i++) {int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);result = Math.max(sum, result);}return result;}
}

3.单调栈法

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

为什么末尾和开头要加0?

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

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

开头为什么要加元素0?

如果栈中只有一个元素,将栈顶弹出得到mid,栈里没有元素了,那么为了避免空栈取值,直接跳过了计算结果的逻辑。

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

  • 情况一:当前遍历的元素heights[i]小于栈顶元素heights[st.top()]的情况
  • 将栈中比当前元素小的都出栈

  • 情况二:当前遍历的元素heights[i]大于栈顶元素heights[st.top()]的情况
  • 直接入栈

  • 情况三:当前遍历的元素heights[i]等于栈顶元素heights[st.top()]的情况
  • 将栈顶的元素更新为当前元素

                                                         图略

代码参考:

class Solution {public int largestRectangleArea(int[] heights) {int result=0;LinkedList<Integer> list=new LinkedList<>();//首尾插入0int[] newHeigths=new int[heights.length+2];System.arraycopy(heights, 0, newHeigths, 1, heights.length);newHeigths[heights.length+1]=0;list.add(0);for(int i=1;i<newHeigths.length;i++){if(newHeigths[i]>newHeigths[list.get(list.size()-1)]){list.add(i);}else if(newHeigths[i]==newHeigths[list.get(list.size()-1)]){//可以省略list.remove(list.size()-1);list.add(i);}else{while(newHeigths[i]<newHeigths[list.get(list.size()-1)]){int mid=list.get(list.size()-1);list.remove(list.size()-1);int left=list.get(list.size()-1);int right=i;int w=right-left-1;int h=newHeigths[mid];result=Math.max(result,w*h);}list.add(i);}}return result;}
}

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

src:源数组;

srcPos:源数组要复制的起始位置;

dest:目的数组;

destPos:目的数组放置的起始位置;

length:复制的长度.

总结:

要解决本题就要快速找到当前位置的左边第一个高度低于当前值的位置和右边第一个高度低于当前值的位置

为什么单调栈能帮我们快速找出这两个位置?

对于栈顶元素,栈顶往栈底方向的下一个元素,是第一个小于当前值的(从栈低到栈顶递增),所以对于单调栈很容易找到左边那个位置,如果接下来即将入栈的元素小于栈顶对应的值,那这个接下来要入栈的元素不就是我们要找的那个右边的那个值吗?

建议与接雨水题目一起思考:

Day62:单调栈 LeedCode503. 下一个更大元素 II 42. 接雨水-CSDN博客

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

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

相关文章

HarmonyOS开发案例:【电子相册】

介绍 如何实现一个简单的电子相册应用的开发&#xff0c;主要功能包括&#xff1a; 实现首页顶部的轮播效果。 实现页面跳转时共享元素的转场动画效果。 实现通过手势控制图片的放大、缩小、左右滑动查看细节等效果。 相关概念 [Swiper]&#xff1a;滑块视图容器&#x…

20230507,LIST容器

学了又忘学了又忘&#xff0c;明知道会忘又不想复习又还得学 LIST容器 1.1 基本概念 链表是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的&#xff1b;链表由一系列结点组成 结点&#xff1a;一个是存储数据元素的数据域&a…

Ubuntu18.04设置SSH密钥登录

我们一般使用 VSCode 、MobaXterm、PuTTY等 SSH 客户端来远程管理 Linux 服务器。但是&#xff0c;一般的密码方式登录&#xff0c;容易有密码被暴力破解的问题。所以&#xff0c;一般我们会将 SSH 的端口设置为默认的 22 以外的端口&#xff0c;或者禁用 root 账户登录。但是即…

值得收藏!修复Windows 10/11中找不到输出或输入设备的五种方法

序言 这篇文章主要关注处理声音输出/输入设备未发现的问题。它提供了许多可行的方法,帮助了许多Windows用户。阅读以下内容以找到你的解决方案。 最近,我将Windows 10更新到21H2,发现我的音频无法工作。当我把鼠标放在任务栏上的声音图标(上面有一个十字图标)上时,它会…

六、文件查找

一、文件查找 1.查找文件内容 ​ 命令&#xff1a;grep keywords /dir_path/filename 2.查找系统命令 ​ 命令&#xff1a;which command 3.查找命令及配置文件位置 ​ 命令&#xff1a;whereis command 4.find查找 ​ find $find_path -name|-type|-perm|-size|-atime…

休斯《公共管理导论》第5版/考研真题解析/章节题库

第一部分 考研真题精选 一、概念题二、简答题三、论述题四、案例分析题第二部分 章节题库 第1章 一个变革的时代第2章 政府的角色第3章 传统的公共行政模式第4章 公共管理第5章 公共政策第6章 治 理第7章 问 责第8章 利害关系人和外部环境第9章 管制、外包和公共企…

Redis(持久化)

文章目录 1.RDB1.介绍2.RDB执行流程3.持久化配置1.Redis持久化的文件是dbfilename指定的文件2.配置基本介绍1.进入redis配置文件2.搜索dbfilename&#xff0c;此时的dump.rdb就是redis持久化的文件3.搜索dir&#xff0c;每次持久化文件&#xff0c;都会在启动redis的当前目录下…

【数据库表的约束】

文章目录 一、NULL vs &#xff08;空字符串&#xff09;二、not null 和default三、列描述字段comment四、zerofill五、primary key 主键总结 一、NULL vs ‘’&#xff08;空字符串&#xff09; NULL和空字符串’’ NULL代表什么都没有。 空字符串’代表有&#xff0c;但串…

致远M3 Session 敏感信息泄露漏洞复现

0x01 产品简介 M3移动办公是致远互联打造的一站式智能工作平台,提供全方位的企业移动业务管理,致力于构建以人为中心的智能化移动应用场景,促进人员工作积极性和创造力,提升企业效率和效能,是为企业量身定制的移动智慧协同平台。 0x02 漏洞概述 致远M3 server多个日志文…

如何做好一个活动策划?

活动策划的关键要素是什么&#xff1f; 首先&#xff0c;要明确一个概念:做活动就是走钢丝&#xff0c;没有保险的高空走钢丝!因为&#xff0c;活动没有“彩排”&#xff0c;只有现场"直播”! 无论什么类型的活动&#xff0c;人数是50人还是2000人&#xff0c;也不论预算…

大数据与会计专业主要学什么课程

大数据与会计专业是一个结合了传统会计知识与现代大数据技术的交叉学科&#xff0c;旨在培养既懂会计又熟悉大数据分析的复合型人才。该专业的学生将会学习以下主要课程内容&#xff1a; 会计基础课程&#xff1a;包括基础会计、财务会计、成本会计、管理会计等&#xff0c;这些…

1天搞定SpringBoot+Vue全栈开发 (8)前端路由VueRouter(进行组件切换)

1.VueRouter安装与使用 2.参数传递 创建路由组件 在项目中定义Discover.vue、Friends.vue、My.vue三个组件&#xff0c;将来要使用vue-router来控制它们的展示与切换&#xff1a; Discover.vue <template><div><h1>发现音乐</h1></div> <…

动态规划——路径问题:LCR 166.珠宝的最高价值

文章目录 题目描述算法原理1.状态表示&#xff08;题目经验&#xff09;2.状态转移方程3.初始化4.填表顺序5.返回值 代码实现CJava 题目描述 题目链接&#xff1a;LCR 166.珠宝的最高价值 算法原理 1.状态表示&#xff08;题目经验&#xff09; 对于这种路径类的问题&…

GORM 与 MySQL(一)

GORM 操作 Mysql 数据库&#xff08;一&#xff09; 温馨提示&#xff1a;以下关于 GORM 的使用&#xff0c;是基于 Gin 框架的基础上&#xff0c;如果之前没有了解过 Gin 可能略微困难。 GORM 介绍 GORM 是 Golang 的一个 orm 框架。简单说&#xff0c;ORM 就是通过实例对象…

ASP.NET网上鲜花销售系统的设计

摘 要 本系统实现了一般电子商务所具备的功能&#xff0c;如商品浏览、用户登录注册、网上与购物、结算、后台数据库管理等&#xff0c;利用这些功能可以对鲜花销售信息进行较好的管理。 网上鲜花销售系统的使用者主要是客户和销售管理者&#xff0c;对于客户来说&#xff0…

Qt | QComboBox(组合框)

01、上节回顾 Qt 基础教程合集02、QComBox 一、QComboBox 类(下拉列表、组合框) 1、QComboBox 类是 QWidget 类的直接子类,该类实现了一个组合框 2、QComboBox 类中的属性 ①、count:const int 访问函数:int count() const; 获取组合框中的项目数量,默认情况下,对于空…

java入门详细教程——day01

目录 1. Java入门 1.1 Java是什么&#xff1f; 1.2 Java语言的历史 1.3 Java语言的分类 1.4 Java语言的特点 1.4.1 先编译再解释运行 1.4.2 跨平台 1.5 JRE和JDK&#xff08;记忆&#xff09; 1.6 JDK的下载和安装&#xff08;应用&#xff09; 1.6.1 下载 1.6.2 安…

新手做抖音小店多久能出单?新手抖音小店出单秘籍!出单教程必看

大家好&#xff0c;我是电商花花。 现阶段还是有很多朋友加入到抖音电商行业&#xff0c;因为抖音小店上还隐藏很多的红利和市场&#xff0c;很多新手开店后第一个问题就是&#xff0c;店铺开通后&#xff0c;一般多久能出单&#xff1f; 多久能出单&#xff0c;其实更看重的…

并发编程之阻塞队列BlockingQueue实战及其原理分析

1. 阻塞队列介绍 1.1 队列 是限定在一端进行插入&#xff0c;另一端进行删除的特殊线性表。 先进先出(FIFO)线性表。 允许出队的一端称为队头&#xff0c;允许入队的一端称为队尾。

分布式与一致性协议之ZAB协议(五)

ZAB协议 ZAB集群如何从故障中恢复 如果我们想把ZAB集群恢复到正常状态&#xff0c;那么新领导者就必须确立自己的领导关系&#xff0c;成为唯一有效的领导者&#xff0c;然后作为主节点"领导"各备份节点一起处理读写请求 如何确立领导关系 前面提到&#xff0c;选…