【每日一题】LeetCode 84.柱状图中最大的矩形(栈、数组、单调栈)

news2024/11/14 22:43:15

【每日一题】LeetCode 84.柱状图中最大的矩形(栈、数组、单调栈)

题目描述

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。

这个题目和接雨水非常类似 点击跳转接雨水 LeetCode 40.接雨水

输入示例

  • 输入:heights = [2,1,5,6,2,3]

  • 输出:10

  • 解释:最大的矩形为图中红色区域,面积为 10

  • 请添加图片描述

  • 输入:heights = [2,4]

  • 输出:4
    请添加图片描述

提示

  • 1 <= heights.length <= 10^5
  • 0 <= heights[i] <= 10^4

思路分析

为了找到最大的矩形面积,我们可以利用单调栈的思想。单调栈可以帮助我们找到每个柱子左边和右边第一个比它矮的柱子的索引。通过这两个索引,我们可以计算出以当前柱子为高的矩形的宽度,从而得到面积,并更新最大面积。

  1. 首先,我们创建两个数组 leftright 来存储每个柱子左边和右边第一个比它矮的柱子的索引。

  2. 我们使用一个栈来维护一个单调递增序列。对于每个柱子,我们从左到右遍历,如果栈不为空且栈顶柱子的高度大于等于当前柱子的高度,我们就一直弹出栈顶元素,直到遇到一个比当前柱子矮的柱子或者栈为空。此时,如果栈为空,则当前柱子的左边界为 -1(表示没有比它矮的柱子),否则为栈顶元素的索引。

  3. 重复上述步骤,但是这次我们从右到左遍历,更新每个柱子的右边界。

  4. 最后,我们遍历每个柱子,计算以它为高的矩形的面积,并更新最大面积。

  5. 在这个问题中,虽然我们使用的是 Deque 接口的实现类 ArrayDeque,但它在这里的作用更像是一个栈,而不是传统意义上的队列。在Java中,Deque 是一个双端队列接口,它扩展了 Queue 接口,除了具有队列的基本操作外,还提供了在两端添加和移除元素的能力。

数据结构的选择

为什么使用 Deque 而不是单纯的 Stack

  1. 功能丰富Deque 提供了两端操作的能力,这意味着你可以从两端添加或移除元素。虽然在这个特定问题中我们主要使用它作为栈(只从一端添加和移除元素),但 Deque 的灵活性允许在需要时轻松地扩展功能。
  2. 性能优化ArrayDeque 是基于数组实现的,它在大多数情况下提供了比 Stack 更好的性能。ArrayDeque 是一个非常高效的双端队列实现,因为它在内存分配和元素访问方面进行了优化。
  3. 扩展性:如果算法稍作修改,需要从两端操作元素,使用 Deque 可以很容易地实现这一点,而不需要重写大量代码。

在这个地方 Deque 比起 Stack 的优势:

  • 栈的模拟:在这个算法中,我们实际上是在模拟栈的行为,即后进先出(LIFO)。ArrayDeque 可以完美地模拟这种行为,因为它提供了 pushpop 方法,这些方法在 ArrayDeque 中的实现非常高效。
  • 内存效率ArrayDeque 通常比基于链表的 Stack 实现更节省内存,因为它使用数组来存储元素,而数组的内存分配是连续的,这有助于减少内存碎片和提高缓存的利用率。
  • 操作速度ArrayDeque 的操作速度通常比 Stack 快,因为它的内部实现优化了内存访问模式,减少了垃圾收集的压力。

请添加图片描述

代码实现

   import java.util.ArrayDeque;
   import java.util.Deque;

   class Solution {
       public int largestRectangleArea(int[] heights) {
           int len = heights.length;
           int[] left = new int[len];
           int[] right = new int[len];

           // 使用单调栈找到每个柱子的左边界
           Deque<Integer> stack = new ArrayDeque<>();
           for (int i = 0; i < len; i++) {
               while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                   stack.pop();
               }
               left[i] = (stack.isEmpty() ? -1 : stack.peek());
               stack.push(i);
           }
       
           // 清空栈,准备找右边界
           stack.clear();
           // 使用单调栈找到每个柱子的右边界
           for (int j = len -
           
           1; j >= 0; j--) {
               while (!stack.isEmpty() && heights[stack.peek()] >= heights[j]) {
                   stack.pop();
               }
               right[j] = (stack.isEmpty() ? len : stack.peek());
               stack.push(j);
           }
       
           // 计算最大矩形面积
           int max = 0;
           for (int i = 0; i < heights.length; i++) {
               max = Math.max(max, (right[i] - left[i] - 1) * heights[i]);
           }
           return max;
       }
   }

题外话

​ 今天,我在解决“柱状图中最大的矩形”这个问题时,经历了一场思维的马拉松。一开始,我像大多数人一样,选择了最直接的暴力方法,但很快我就意识到,这种方法在数据量稍大时就会显得力不从心。这不仅是对我的编程技能的挑战,更是对我的耐心和决心的考验。

​ 在与同学的激烈讨论和很多次的图解、代数推导之后,我们终于找到了使用单调栈的解决方案。这个过程虽然漫长,但每当我解决一个难题,那种成就感和喜悦是难以言表的。我仿佛能感受到数据结构的“无情”,它不会因为你的困惑而放慢脚步,但同时,它也像一位严师,引导你走向更深层次的理解。

​ 这个经历让我深刻体会到,算法的世界充满了挑战,但也充满了惊喜。每当我AC的那一刻,我都能感受到一种难以抑制的激动,那是对自己努力的肯定,也是对未来的无限憧憬。

​ 我想对所有在算法道路上奋斗的朋友们说:不要害怕困难,因为每一次的挑战都是我们成长的催化剂。让我们保持热情,保持好奇心,一起探索算法的奥秘,一起遇见更好的自己。在这条充满挑战的道路上,每一次的AC都是我们前进的动力,每一次的思考都是我们智慧的积累。

​ 感谢大家的阅读,我期待与你们在算法的世界里相遇,一起成长,一起进步,一起遇见更好的自己吧!

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

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

相关文章

Linux小程序:进度条

目录 一、换行与回车 二、缓冲区 三、倒计时代码 四、进度条实现 实现进度条程序&#xff0c;首先需要两个预备知识&#xff1a; 1.换行与回车 2.缓存区 一、换行与回车 我们通常使用\n作为换行符&#xff0c;但实际上\n是换行回车两种效果的结合&#xff0c;因此我们需…

.iso文件怎么打开?

在日常使用电脑的过程中&#xff0c;很多用户都会遇到.iso文件&#xff0c;尤其是在安装软件、操作系统或者备份光盘内容时。那么&#xff0c;什么是.iso文件&#xff1f;该如何打开它&#xff1f;本文将为大家详细解答这些问题&#xff0c;帮助大家轻松处理.iso文件。 什么是.…

IEEE TRO 人形机器人遥操作的综述

人形机器人的遥操作结合了人类的认知技能和领域专业知识以及人形机器人的物理能力。这种人形机器人的操作多功能性使它们成为远程环境中各种应用的理想平台。然而&#xff0c;人形机器人的复杂性给遥操作带来了挑战&#xff0c;尤其是在通信受限的非结构化动态环境中。尽管在过…

【2024国赛B题】高教杯全国大学生数学建模国赛建模过程+完整代码论文全解全析

你是否在寻找数学建模比赛的突破点&#xff1f;数学建模进阶思路&#xff01; 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024国赛数学建模竞赛&#xff08;B题&#xff09;的全面解析。这个解决方案包不仅包括完整的代码实现&#xff0c;还有详尽的建模过程和解析…

pdf怎么删除其中一页?这5个pdf编辑方法新手都在用,建议收藏

pdf怎么删除其中一页&#xff1f;在日常的工作和学习生活中&#xff0c;我们经常会遇到需要处理PDF文件的情况。有时候&#xff0c;我们在处理PDF文件时&#xff0c;发现某些页面内容不再需要&#xff0c;想从PDF中删除特定的页面。然而&#xff0c;很多小伙伴对PDF的编辑和修改…

员工上班摸鱼怎么办,上班期间摸鱼

在现代企业的日常运营中&#xff0c;员工的工作效率是企业成功的关键因素之一。随着远程办公的普及&#xff0c;员工在工作中“摸鱼”的现象愈加频繁。这不仅会导致工作效率的下降&#xff0c;还可能拖延项目进展&#xff0c;增加企业的管理成本。面对这一问题&#xff0c;企业…

大模型备案重难点最详细说明【评估测试题+附件】

2024年3月1日&#xff0c;我国通过了《生成式人工智能服务安全基本要求》&#xff08;以下简称《AIGC安全要求》&#xff09;&#xff0c;这是目前我国第一部有关AIGC服务安全性方面的技术性指导文件&#xff0c;对语料安全、模型安全、安全措施、词库/题库要求、安全评估等方面…

极市开发平台yolov8训练无人机数据集样例数据流程

先进入vscode&#xff0c;进入src_repo文件夹。 第一步&#xff0c;克隆一个比较好的博主的库&#xff1a; GitHub - Incalos/YOLO-Datasets-And-Training-Methods: This project involves making custom datasets for the YOLO series and model training methods for YOLO.…

在生产线打包机中RFID技术的赋能

在生产线打包机中RFID技术的赋能 随着制造业的智能化发展&#xff0c;RFID技术越来越多地被应用于生产线中&#xff0c;特别是在产线打包环节。本文将探讨RFID技术如何提高产线打包机的工作效率和准确性&#xff0c;并分析其在现代制造业中的重要作用。 RFID在产线打包机上的应…

顶刊速递|医学AI在乳腺癌中的最新研究进展·24-09-06

小罗碎碎念 本期推文主题&#xff1a;乳腺癌 最近我在思考一个问题&#xff0c;生信分析和人工智能的区别和联系是什么&#xff1f;细节现在是想不清楚的&#xff0c;因为我的知识储备还不够&#xff0c;但是有一点我可以确定&#xff0c;二者的部分本质都是一样的——强大的计…

使用程序方式获取与处理MySQL表数据

8.1  执行多条语句获取 MySQL 表数据 8.1.1  MySQL 中的常量 8.1.2  MySQL 中的变量 1&#xff0e;用户变量 用户可以在表达式中使用自己定义的变量&#xff0c;这样的变量称为用户变量。 用户变量在使用前必须定义和初始化&#xff0c;如果使用没有初始化的变量&#x…

EG边缘计算网关连接华为云物联网平台(MQTT协议)

需求概述 实现一个流程&#xff1a;EG8200mini采集Modbus RTU数据&#xff0c;通过MQTT协议连接华为云物联网平台 Modbus RTU采集此处不做过多赘述&#xff0c;可参考其他案例&#xff08;串口读取Modbus传感器数据&#xff09;介绍。下文默认已经采集到Modbus RTU数据。 要…

【B题成品论文已出】24数学建模国赛B题成品论文(附参考代码)免费分享

B题&#xff1a;生产过程中的决策问题 一、第一问 针对问题一&#xff0c;要求我们制定多种抽样方案&#xff0c;并利用区间估计的方法确定各个抽样方案的检测次数&#xff0c;在两种情形下确定抽样方法。这里可以选择的抽样方案有简单随机抽样&#xff08;超几何分布中未知参…

详解 MQ 消息队列

谈起消息队列&#xff0c;内心还是会有些波澜。 消息队列&#xff0c;缓存&#xff0c;分库分表是高并发解决方案三剑客&#xff0c;而消息队列是我最喜欢&#xff0c;也是思考最多的技术。 我想按照下面的四个阶段分享我与消息队列的故事&#xff0c;同时也是对我技术成长经…

ICAS英格尔认证碳中和技术项目入选联合国工发组织第三届碳中和技术方案征集,打造农食系统碳足迹管理“智囊”

2024年8月27日&#xff0c;由联合国工业发展组织上海ITPO与上海交大-联合国工发绿色增长联合研究院联合主办的“虹口双碳对话第三届碳中和技术方案征集暨UNIDO Global Call 2024中国项目储备评估会”在上海环境能源交易所成功举办。 中国科学院地理科学与资源研究所陆地表层格…

【银河麒麟高级服务器操作系统实例】虚拟化平台系统服务中断现象分析及处理建议

服务器环境以及配置 【机型】虚机 处理器&#xff1a; Kunpeng-920 内存&#xff1a; 40G 【内核版本】 4.19.90-23.8.v2101.ky10.aarch64 【OS镜像版本】 银河麒麟操作系统 Kylin-Server-10-SP1-Release-Build20-20210518-arm64 【第三方软件】 智能运维系统、mysq…

Flume 日志采集系统

Flume 日志采集系统 一、Flume 概述二、Flume 架构设计2.1 架构图2.2 Flume Source 类型2.3 Flume Channel 类型2.4 Flume Sink 类型 三、Flume 安装部署3.1 下载解压3.2 上传解压3.3 修改配置文件2.4 启动 Flume Agent 四、案例实践&#xff1a;Flume 分布式集群搭建4.1 Flume…

使用 StatisticalOutlierRemoval 过滤器删除离群值

下载数据集 table_scene_lms400.pcd 并将其保存到磁盘的某个位置。 然后&#xff0c;创建一个文件&#xff0c;比如说&#xff0c;在你的收藏夹中 编辑器&#xff0c;并将以下内容放入其中&#xff1a;statistical_removal.cpp #include <iostream> #include <pcl/i…

安科瑞光伏三相电子式导轨电表ADL400N-CT双向计量防逆流自带互感器电表

概述 ADL系列导轨式多功能电能表&#xff0c;是主要针对于光伏并网系统、微逆系统、储能系统、交流耦合系统等新能源发电系统而设计的一款智能仪表&#xff0c;产品具有精度高、体积小、响应速度快、安装方便等优点。具有对电力参数进行采样计量和监测&#xff0c;逆变器或者能…

rancher搭建k8s及jenkins自动化部署

1、准备环境 角色IP用途k8s-rancher-master192.168.3.63master节点k8s-rancher-node01192.168.3.64node节点k8s-rancher-node02192.168.3.66node节点k8s-rancher-server192.168.2.33rancher-server节点注: 服务器名需要配置不同,相同服务器名不能加入node节点 在所有节点进行…