leetcode84. 柱状图中最大的矩形(单调栈-java)

news2024/10/7 18:23:45

柱状图中最大的矩形

  • leetcode84. 柱状图中最大的矩形
    • 题目描述
    • 单调栈加数组优化栈结构解题
    • 代码演示
    • 用数组来优化栈结构,时间会更快
  • 单调栈专题

leetcode84. 柱状图中最大的矩形

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/largest-rectangle-in-histogram

题目描述

给定 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

单调栈加数组优化栈结构解题

思路大致如下:
去遍历这个数组,每到一个数字时,我们就找出能以当前数字为最小值的子数组的范围,知道范围后,我们就可以求出其最大矩形的大小.遍历所有位置后,就可以得出最大值了.

具体流程:
首先我们枚举某一根柱子 ii 作为高 h=heights[i];
随后我们需要进行向左右两边扩展,使得扩展到的柱子的高度均不小于 h。换句话说,我们需要找到左右两侧最近的高度小于 h 的柱子,这样这两根柱子之间(不包括其本身)的所有柱子高度均不小于 h,并且就是 i 能够扩展到的最远范围。

我们用一个具体的例子 [6,7,5,2,4,5,9,3]来理解单调栈。我们需要求出每一根柱子的左侧且最近的小于其高度的柱子。初始时的栈为空。

我们枚举 6,因为栈为空,所以 6 左侧的柱子是「哨兵」,位置为 -1。随后我们将 6 入栈。
栈:[6(0)]。(这里括号内的数字表示柱子在原数组中的位置)
我们枚举 7,由于 6<7,因此不会移除栈顶元素,所以 7 左侧的柱子是 6,位置为 0。随后我们将 7 入栈。
栈:[6(0), 7(1)]

我们枚举 5,由于 7≥5,因此移除栈顶元素 7。同样地,6≥5,再移除栈顶元素 6。此时栈为空,所以 5 左侧的柱子是「哨兵」,位置为 −1。随后我们将 5 入栈。
    栈:[5(2)]

接下来的枚举过程也大同小异。我们枚举 2,移除栈顶元素 5,得到 2 左侧的柱子是「哨兵」,位置为 −1。将 2 入栈。
    栈:[2(3)]

我们枚举 4,5 和 9,都不会移除任何栈顶元素,得到它们左侧的柱子分别是 2,4和 5,位置分别为 3,4 和 5。将它们入栈。
    栈:[2(3), 4(4), 5(5), 9(6)]

我们枚举 3,依次移除栈顶元素 9,5 和 4,得到 3 左侧的柱子是 2,位置为 3。将 3 入栈。
    栈:[2(3), 3(7)]

这样以来,我们得到它们左侧的柱子编号分别为[−1,0,−1,−1,3,4,5,3]。用相同的方法,我们从右向左进行遍历,也可以得到它们右侧的柱子编号分别为 [2,2,3,8,7,7,7,8],这里我们将位置 8 看作「哨兵」。
在得到了左右两侧的柱子之后,我们就可以计算出每根柱子对应的左右边界,并求出答案了。

分析
单调栈的时间复杂度是多少?直接计算十分困难,但是我们可以发现:
每一个位置只会入栈一次(在枚举到它时),并且最多出栈一次。
因此当我们从左向右/总右向左遍历数组时,对栈的操作的次数就为 O(N)。所以单调栈的总时间复杂度为 O(N)。

代码演示

/**
	 * 单调栈
	 * @param height
	 * @return
	 */
	public static int largestRectangleArea1(int[] height) {
		if (height == null || height.length == 0) {
			return 0;
		}
		int maxArea = 0;
		Stack<Integer> stack = new Stack<Integer>();
		for (int i = 0; i < height.length; i++) {
			while (!stack.isEmpty() && height[i] <= height[stack.peek()]) {
				int j = stack.pop();
				int k = stack.isEmpty() ? -1 : stack.peek();
				int curArea = (i - k - 1) * height[j];
				maxArea = Math.max(maxArea, curArea);
			}
			stack.push(i);
		}
		while (!stack.isEmpty()) {
			int j = stack.pop();
			int k = stack.isEmpty() ? -1 : stack.peek();
			int curArea = (height.length - k - 1) * height[j];
			maxArea = Math.max(maxArea, curArea);
		}
		return maxArea;
	}

用数组来优化栈结构,时间会更快

	/**
	 * 单调栈, 数组来优化栈
	 * @param height
	 * @return
	 */
	public static int largestRectangleArea2(int[] height) {
		if (height == null || height.length == 0) {
			return 0;
		}
		int N = height.length;
		//用数组来优化栈
		int[] stack = new int[N];
		//记录数组的有边界的位置
		int si = -1;
		//记录最大面积
		int maxArea = 0;
		for (int i = 0; i < height.length; i++) {
			while (si != -1 && height[i] <= height[stack[si]]) {
				int j = stack[si--];
				int k = si == -1 ? -1 : stack[si];
				int curArea = (i - k - 1) * height[j];
				maxArea = Math.max(maxArea, curArea);
			}
			//加入到队列中
			stack[++si] = i;
		}
		while (si != -1) {
			int j = stack[si--];
			int k = si == -1 ? -1 : stack[si];
			int curArea = (height.length - k - 1) * height[j];
			maxArea = Math.max(maxArea, curArea);
		}
		return maxArea;
	}

单调栈专题

单调栈的实现-单调递减栈和单调递增栈

leetcode1856. 子数组最小乘积的最大值

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

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

相关文章

01、Linux运维发展与学习路线图

目录 一、Linux运维行业前景二、运维相关岗位三、Linux运维岗位薪酬四、Linux运维岗知识框架4.1、常见站点系统架构演变1 单机2 多机3 缓存4 向外扩展5 Docker 4.2 知识体系框架图4.3 技术人员成长的阶段4.4 方法论 一、Linux运维行业前景 流程化、标准化的工作越来越依赖于信…

结构光三维测量几种比较成熟的方法

1.飞行时间发 原理:通过直接测量光传播的时间,确定物体的面型。发射脉冲信号,接受发射回的光,计算距离。 精度:毫米级 优点:原理简单,可避免阴影和遮挡等问题,且仪器便携化。 缺点:精度相对较低 2.莫尔条纹法 原理:采用两组光栅,一个主光栅,一个基准光栅,通过…

vue + element 笔记

1.安装nodejs&#xff0c;cmd中运行 node -v 验证是否成功 2.安装cnpm&#xff0c;cmd中运行 npm install -g cnpm --registryhttps://registry.npm.taobao.org&#xff0c;cmd中 cnpm -v 验证是否成功 3.安装vue-cli&#xff0c;cmd中运行 cnpm install --global vue-cli&…

【Spark】介绍,部署与快速入门

文章目录 介绍核心模块Spark CoreSpark SQLSpark StreamingSpark MLlibSpark GraphX 部署命令行Web UI提交应用Local 模式Standalone配置文件添加 JAVA_HOME 环境变量和集群对应的 master 节点启动集群配置历史服务添加日志存储路径添加日志配置webui 配置高可用 Yarn模式配置文…

老照片修复:模糊褪色有划痕的老旧照片如何修复?

在我们的生活中&#xff0c;照片是记录我们生活的重要方式之一。无论是在手机相册里还是在家中的相册里&#xff0c;我们都有很多珍贵的照片&#xff0c;但是随着时间的推移&#xff0c;照片也会老化&#xff0c;甚至出现褪色、划痕、折痕、破损、发霉等情况&#xff0c;这些情…

java多线程使用与踩坑

SpringBoot使用多线程简单方法&#xff1a;地址 线程安全查阅资料参考&#xff1a;地址 背景&#xff1a; 经过上述资料查看&#xff0c;我想写个方法&#xff08;依靠notify()唤醒&#xff0c;依靠wait()等待&#xff09;实现两个线程轮流打印。 实现&#xff1a; 1.线程池配…

HCIA复习二---7月4

路由&#xff1a; 按照路由条目&#xff0c;逻辑选址。 控制层面&#xff1a;路由条目的加表&#xff1a;AD metric&#xff08;华为 priority cost&#xff09;&#xff1b; 数据层面&#xff1a;按照路由条目转发数据包---与操作---最长匹配---递归查找&#xff1b; 静态…

第四十三周周报

学习目标&#xff1a; latent-diffusion 代码 学习时间&#xff1a; 2023.06.17 - 2023.06.30 学习产出&#xff1a; 一、代码 1、前置知识&#xff1a;PyTorch Lightning执行顺序 执行顺序&#xff1a; trainer.fit(model)&#xff1a;开始训练模型。 prepare_data()&a…

教你如何将纬地数据与实景三维模型进行叠加

概述&#xff1a; 纬地是公路设计的常用软件&#xff0c;在国内的普及率很高。传统的纬地数据文件以二维线条形式呈现在CAD中。本文提出了一种新思路、新方法&#xff0c;即将纬地的设计成果与无人机航拍的高精度倾斜摄影模型叠加在一起&#xff0c;辅助设计方案复核。 ​纬地…

SpringBoot第19讲:SpringBoot 如何保证接口幂等

SpringBoot第19讲&#xff1a;SpringBoot 如何保证接口幂等 在以SpringBoot开发Restful接口时&#xff0c;如何防止接口的重复提交呢&#xff1f; 本文是SpringBoot第19讲&#xff0c;主要介绍接口幂等相关的知识点&#xff0c;并实践常见基于Token实现接口幂等。 文章目录 Spr…

培训报名小程序实战开发

目录 1 需求描述2 原型绘制2.1 首页2.2 报名列表页2.3 报名页2.4 支付页面2.5 支付成功页面2.6 我的页面2.7 我的报名页面2.8 报名详情页面 3 数据源设计4 数据源开发5 创建模型应用6 录入测试数据7 创建自定义应用8 创建页面总结 经常有人问&#xff0c;低代码学习容易么&…

c语言进阶-枚举、联合(共用体)

枚举 枚举项也有值属性 修改枚举项值属性 枚举的优点 define的实现过程 实际在预处理已经完成了M - 100 的替换&#xff0c;实际执行是int m 100&#xff1b; enum调试的时候更方便&#xff0c;代码变化过程都可以看到。 联合&#xff08;共用体&#xff09; 打印出来的三个…

前端学习——HTML5

新增语义化标签 新增布局标签 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content&qu…

无限极 × 盖雅工场|劳动力管理系统项目正式启动,为多工厂管理保驾护航

6月12日&#xff0c;无限极盖雅工场劳动力管理系统启动大会在广东江门举行。无限极IT供应链系统负责人毛松和、智能制造总监胡波、新会生产中心负责人胡流云、营口生产中心负责人源博恩和人才资源共享服务负责人林岳&#xff0c;以及盖雅工场华南总经理潘磊等出席了启动大会。 …

ARM day6 (标准pin引脚启动)

A7核 led.h #ifndef __LED_H__ #define __LED_H__//寄存器封装 //声明一个结构体 typedef struct {volatile unsigned int MODER; //00volatile unsigned int OTYPER; //04volatile unsigned int OSPEEDR; //08volatile unsigned int PUPDR; //0Cvolatile unsigned int …

“全球筷子第一股”双枪科技携手纷享销客连接型CRM

近日&#xff0c;纷享销客携手双枪科技股份有限公司&#xff08;以下简称“双枪”&#xff09;&#xff0c;“主数据与订货管理系统”项目启动会在浙江杭州举行&#xff0c;双枪和纷享销客双方多位高管共同出席了当天的启动会&#xff0c;并针对双方项目组的紧密合作给予了一致…

【C++面向对象】用电管理数据管理系统(面向对象)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、51CTO技术博主 &#x…

word转化为ftl格式文件模板,导出后office提示文件错误

需求如下: 使用模板,导出word文件,最近在做这个需求,本地环境用的是wps,结合本地的环境快速完成了开发需求之后,有一天客户发现office打开报错,本人深感不接,wps都能打开,各个在线文档也都支持,为何office就不支持,环境不同。 分析: wps是按照office版本迭代开发…

对比学习论文-系列4

文章目录 MedCLIP: Contrastive Learning from Unpaired Medical Images and Text目标问题来源模型架构 Supervised Prototypical Contrastive Learning for Emotion Recognition in ConversationPrototypical Contrastive LearningCurriculum Strategy&#xff1a; KECP: Know…

Lion:闭源大语言模型的对抗性蒸馏

通过调整 70k 指令跟踪数据&#xff0c;Lion (7B) 可以实现 ChatGPT 95% 的能力&#xff01; 消息 我们目前正在致力于训练更大尺寸的版本&#xff08;如果可行的话&#xff0c;13B、33B 和 65B&#xff09;。感谢您的耐心等待。 **[2023年6月10日]**我们发布了微调过程中解…