算法练习题14——leetcode84柱形图中最大的矩形(单调栈)

题目描述: 

解题思路:

要解决这个问题,我们需要找到每个柱子可以扩展的最大左右边界,然后计算以每个柱子为高度的最大矩形面积。

具体步骤如下:

  1. 计算每个柱子左侧最近的比当前柱子矮的位置

    • 使用一个单调栈(栈中保存元素索引)从左到右遍历柱子,确保栈中元素始终保持递增(从栈底到栈顶)。
    • 如果当前柱子的高度小于栈顶柱子的高度,则不断弹出栈顶元素,直到找到一个高度小于当前柱子的元素为止。
    • 这样可以确定每个柱子左边第一个比它矮的位置。
  2. 计算每个柱子右侧最近的比当前柱子矮的位置

    • 使用类似的单调栈方法,从右到左遍历柱子,确保栈中元素始终保持递增。
    • 同样地,可以确定每个柱子右边第一个比它矮的位置。
  3. 计算最大矩形面积

    • 计算每个柱子可以扩展的宽度,使用公式 (right[i] - left[i] - 1) * heights[i] 来计算以该柱子为高度的矩形面积。
    • 遍历所有柱子,找到最大面积。

代码示例: 

class Solution {public int largestRectangleArea(int[] heights) {int n = heights.length;int[] left = new int[n]; // 用于存储每个柱子的左边界int[] right = new int[n]; // 用于存储每个柱子的右边界Stack<Integer> stack = new Stack<>(); // 用于计算左右边界的单调栈// 从左到右遍历柱子,计算每个柱子左边第一个比它矮的位置for (int i = 0; i < n; i++) {// 如果栈不为空且栈顶柱子的高度大于等于当前柱子的高度,弹出栈顶元素while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {stack.pop();}// 如果栈为空,说明当前柱子左侧没有比它矮的柱子if (stack.isEmpty()) {left[i] = -1; // 左边界为-1} else {left[i] = stack.peek(); // 栈顶元素即为左边第一个比当前柱子矮的位置}// 将当前柱子的索引压入栈中stack.push(i);}stack.clear(); // 清空栈,用于计算右边界// 从右到左遍历柱子,计算每个柱子右边第一个比它矮的位置for (int i = n - 1; i >= 0; --i) {// 如果栈不为空且栈顶柱子的高度大于等于当前柱子的高度,弹出栈顶元素while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {stack.pop();}// 如果栈为空,说明当前柱子右侧没有比它矮的柱子if (stack.isEmpty()) {right[i] = n; // 右边界为n} else {right[i] = stack.peek(); // 栈顶元素即为右边第一个比当前柱子矮的位置}// 将当前柱子的索引压入栈中stack.push(i);}int ans = 0; // 用于存储最大矩形面积// 遍历每个柱子,计算以该柱子为高度的最大矩形面积for (int i = 0; i < n; i++) {// 以heights[i]为高度的矩形面积计算公式为:(right[i] - left[i] - 1) * heights[i]ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);}return ans; // 返回最大矩形面积}
}

详细解题步骤:

  1. 初始化数组和栈

    • left[i] 存储柱子 i 左侧第一个比其矮的柱子的索引,如果不存在,设置为 -1
    • right[i] 存储柱子 i 右侧第一个比其矮的柱子的索引,如果不存在,设置为 n
    • 使用 Stack 存储柱子的索引,用于计算左右边界。
  2. 计算左边界

    • 遍历所有柱子:
      • 如果当前柱子的高度小于栈顶柱子的高度,弹出栈顶元素,直到找到一个高度小于当前柱子的元素。
      • 如果栈为空,说明当前柱子左侧没有比它矮的柱子,设置 left[i] = -1
      • 否则,设置 left[i] = stack.peek(),即栈顶元素是左边第一个比当前柱子矮的位置。
    • 将当前柱子的索引压入栈中。
  3. 计算右边界

    • 从右到左遍历所有柱子:
      • 使用类似的方法计算每个柱子右边第一个比它矮的位置。
  4. 计算最大矩形面积

    • 遍历所有柱子,以每个柱子作为最矮柱子,计算矩形的最大面积。
    • 使用公式 (right[i] - left[i] - 1) * heights[i] 来计算每个柱子的最大矩形面积。

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

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

相关文章

java后端保存的本地图片通过ip+端口直接访问

直接上代码吧 package com.ydx.emms.datapro.controller;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.…

函数式接口实现策略模式

函数式接口实现策略模式 1.案例背景 我们在日常开发中&#xff0c;大多会写if、else if、else 这样的代码&#xff0c;但条件太多时&#xff0c;往往嵌套无数层if else,阅读性很差&#xff0c;比如如下案例&#xff0c;统计学生的数学课程的成绩&#xff1a; 90-100分&#…

idea添加本地环境执行模版

用Flink的环境执行时&#xff0c;因为最后会打包放服务器&#xff0c;所以有些jar包将不会打包上传&#xff0c;这些jar包用<scope>provided</scope>标记 所以这些jar包在本地运行时也会不提供&#xff0c;为了程序在本地能跑&#xff0c;我们每次执行是需手动添加…

JAVA-接口(一万四千字讲解)

目录 一、接口的概念 二、语法规则 三、接口使用 四、接口特性 五、实现多个接口 六、接口间的继承 七、接口使用实例 1.Comparable 2.写一个自己的sort 3.Comparator 八、类的克隆Clonable 1.Clonable接口 2.浅拷贝 3.深拷贝 九、抽象类和接口的区别 十、 Obje…

芯片时钟树评估的关键性能参数

前面有很多文章都介绍了PI性能的影响&#xff0c;也介绍了PSIJ对信号或时钟性能的影响&#xff0c;对于SOC设计&#xff0c;为了更好的理解电源完整性在芯片设计中的重要作用&#xff0c;对芯片的时钟树设计需要足够理解才能更好的明白电源完整性的影响。 时钟分布网络设计一直…

最基本的SELECT...FROM结构

第0种&#xff1a;最基本的查询语句 SELECT 字段名&#xff0c;字段名 FROM 表名 SELECT 1&#xff1b; SELECT 11,3*2&#xff1b; FROM SELECT 11,3*2 FROM DUAL&#xff1b;#dual&#xff1a;伪表 我们可以用它来保持一个平衡 这里我们的值不需要在任何一个表里&#xf…

9、类和对象

9.1 封装 9.1.1 封装的例子 class Student { public:string name;int age; public:void setName(string name_) {name name_;} }; int main() {Student s1;s1.setName("zhangsan");return 0; }类中的行为都叫做成员&#xff0c;例如成员属性&#xff0c;成员变量&…

飞速(FS)S5800-48T4S:如何使用MLAG?

MLAG&#xff08;多机箱链路聚合组&#xff09;可实现无缝故障转移并优化带宽利用率&#xff0c;从而增强网络冗余和提高可扩展性。它允许多台交换机作为一个统一实体运行&#xff0c;从而降低停机风险并确保网络运行不中断。飞速&#xff08;FS&#xff09;S5800-48T4S是一款支…

二维高斯函数的两种形式

第一种形式很常见 多元正态分布 多元正态分布&#xff08;Multivariate Normal Distribution&#xff09;&#xff0c;也称为多变量正态分布或多维正态分布&#xff0c;是统计学中一种重要的概率分布&#xff0c;用于描述多个随机变量的联合分布。 假设有 n n n 个随机变量…

【LabVIEW学习篇 - 18】:人机界面交互设计02

文章目录 错误处理函数简单错误处理器通用错误处理器清楚错误合并错误错误代码至错误簇转换查找第一个错误 鼠标指针 错误处理函数 在LabVIEW中&#xff0c;是通过错误输入簇和错误输出簇来传递错误信息&#xff0c;可以将底层错误信息传递到上层VI。设计人员需要对不同程度的…

2024 数学建模高教社杯 国赛(C题)| 农作物的种植策略 | 建模秘籍文章代码思路大全

铛铛&#xff01;小秘籍来咯&#xff01; 小秘籍团队独辟蹊径&#xff0c;运用等多目标规划等强大工具&#xff0c;构建了这一题的详细解答哦&#xff01; 为大家量身打造创新解决方案。小秘籍团队&#xff0c;始终引领着建模问题求解的风潮。 抓紧小秘籍&#xff0c;我们出发…

高并发内存池(一):项目介绍与定长内存池的实现

目录​​​​​​​ 项目介绍 池化技术 内存池 内存碎片 malloc工作原理 定长内存池 申请内存 释放内存 定位new VirtualAlloc函数 封装VirtualAlloc 定长内存池的最终代码 项目介绍 项目原型&#xff1a;goole的开源项目tcmalloc&#xff08;Thread-Caching Mal…

CIOE中国光博会&电巢科技即将联办“智能消费电子创新发展论坛”

在科技浪潮汹涌澎湃的当下&#xff0c;从通信领域的高速光传输&#xff0c;到消费电子中的高清显示与先进成像技术&#xff0c;光电技术的应用范围不断拓展且日益深化。而AIGC 凭借其丰富的内容供给与个性化反馈能力&#xff0c;正为新一代消费电子及智能穿戴产品开辟崭新的发展…

前端请求的路径baseURL怎么来的 ?nodejs解决cors问题的一种方法

背景&#xff1a;后端使用node.js搭建&#xff0c;用的是express 前端请求的路径baseURL怎么来的 &#xff1f; 前后端都在同一台电脑上运行&#xff0c;后端的域名就是localhost&#xff0c;如果使用的是http协议&#xff0c;后端监听的端口号为3000&#xff0c;那么前端请求…

S3C2440开发板:时钟,PWM定时器控制蜂鸣器发声

时钟 时钟和电源管理模块由三部分组成&#xff1a;时钟控制&#xff0c;USB 控制和电源控制。 S3C2440A 中的时钟控制逻辑可以产生必须的时钟信号&#xff0c;包括 CPU 的 FCLK&#xff0c;AHB 总线外设的 HCLK 以及 APB 总线外设的 PCLK。S3C2440A 包含两个锁相环&#xff08…

VBA进行excel坐标转换

在Excel里利用坐标绘图时&#xff0c;可以比较容易想到采用数据透视表&#xff0c;但是数据透视表生成的图不可更改&#xff0c;因此本案例采用VBA进行坐标变换而不改变原始值来转换图像&#xff0c;即实现图像的左右翻转和上下翻转&#xff0c;如下图所示&#xff0c;选择map的…

fastadmin 文件上传腾讯云

1-安装腾讯云SDK composer require qcloud/cos-sdk-v5 2-腾讯云配置 <?phpnamespace app\common\controller;use Qcloud\Cos\Client; use think\Controller; use think\Db;class Tencent extends Controller {/*** 上传文件* param $config* param $key* return array*/p…

Linux下快速判断当前终端使用的是bash or csh

在Linux下设置环境变量的时候&#xff0c;可能你也遇到过export: Command not found一类的错误。这是因为当前终端使用的不是bash&#xff0c;如何快速判断当前终端使用的是哪种类型的shell呢&#xff1f; echo $0判断shell类型 最简单的方法就是在终端输入echo $0&#xff0…

每日一题,零基础入门FPGA——工程师在线精讲来咯

传送门&#xff1a;zzfpga.com/StudentPlatform/Train/StudentArticleDetails?id149

M3U8工作原理以及key解密视频流详解

文章目录 前言一、M3U8是什么&#xff1f;二、HLS—M3U8的工作原理1.分段视频流2.生成播放列表3.客户端请求和解析4.片段下载和播放 三、.m3u8文件内部是什么样的&#xff1f;四、简单介绍下AES-128算法五、拿到KEY后如何去解密&#xff1f;1.手动解密.ts文件2.前人栽树&#x…