【C++单调队列】1438. 绝对差不超过限制的最长连续子数组|1672

news2024/9/30 7:50:57

本文时间知识点

C++队列、双向队列

LeetCode1438. 绝对差不超过限制的最长连续子数组

给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。
如果不存在满足条件的子数组,则返回 0 。
示例 1:
输入:nums = [8,2,4,7], limit = 4
输出:2
解释:所有子数组如下:
[8] 最大绝对差 |8-8| = 0 <= 4.
[8,2] 最大绝对差 |8-2| = 6 > 4.
[8,2,4] 最大绝对差 |8-2| = 6 > 4.
[8,2,4,7] 最大绝对差 |8-2| = 6 > 4.
[2] 最大绝对差 |2-2| = 0 <= 4.
[2,4] 最大绝对差 |2-4| = 2 <= 4.
[2,4,7] 最大绝对差 |2-7| = 5 > 4.
[4] 最大绝对差 |4-4| = 0 <= 4.
[4,7] 最大绝对差 |4-7| = 3 <= 4.
[7] 最大绝对差 |7-7| = 0 <= 4.
因此,满足题意的最长子数组的长度为 2 。
示例 2:
输入:nums = [10,1,2,4,7,2], limit = 5
输出:4
解释:满足题意的最长子数组是 [2,4,7,2],其最大绝对差 |2-7| = 5 <= 5 。
示例 3:
输入:nums = [4,2,2,2,4,4,2,2], limit = 0
输出:3
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 109
0 <= limit <= 109

滑动窗口(错误解法)

i从小到大枚举nums[i],令nums[i1…i]是符合条件的子数组。
由于abs(i1-1,nums[i])>limit,故nums[i1-1…i1+1]一定不符合条件,故从i1可以判断。
如果nums[i1]和nums[i+1]符合条件,则i1++。
错误原因:nums[i1+2]可以和nums[i]不符合

滑动窗口+有序映射(集合)

记录nums[i1…i]的值和下标。如果set最小的值和nums[i]超过限制,则将下标小于等于最小值下标的删除。set最大值超限,也是如此。处理完超限后,将nums[i]放到set。此时的set.size就是以 nusm[i]结尾的最长子数组长度。
时间复杂度:O(nlogn)

滑动窗口+单调队列

两个双向队列分别记录(nums[i],i) ,其中i ∈ \in [0,j-1]。
minQue如果有元素x,其下标为i1 ,符合小于x <nums[i]- limit,则删除下标小于等于i1的元素。
i1 <i2,且nums[i1]>= nums[i2] 。如果i1符合条件,则i2也一定符合。而i2符合会删除i1。故i1可以省略,或者说i1被i2淘汰后。
淘汰后,从队首到队尾,严格升序,即最小元素在队首。
maxQue类似,严格降序。
队首可能有多个元素超限,一个队列超限后,要清理另一个队列的下标。
时间复杂度:O(n)

代码

核心代码

class Solution {
		public:
			int longestSubarray(vector<int>& nums, int limit) {
				deque<int> minQue, maxQue;
				int ans = 0;
				int del = -1;
				for (int i = 0; i < nums.size(); i++) {					
					while (minQue.size() && (nums[minQue.front()] < nums[i] - limit )) {
						del = max(del, minQue.front());
						minQue.pop_front();
					}
					while (maxQue.size() && (nums[maxQue.front()] > nums[i] + limit)) {
						del = max(del, maxQue.front());
						maxQue.pop_front();
					}
					while (minQue.size() && (minQue.front() <= del)) { minQue.pop_front(); }
					while (maxQue.size() && (maxQue.front() <= del)) { maxQue.pop_front(); }					
					while (minQue.size() && (nums[minQue.back()] >= nums[i])) {
						minQue.pop_back();
					}
					while (maxQue.size() && (nums[maxQue.back()] <= nums[i])) {
						maxQue.pop_back();
					}
					minQue.emplace_back(i);
					maxQue.emplace_back(i);
					ans = max(ans, i - del);
				}
				return ans;
			}
		};

单元测试

	vector<int> nums;
		int limit;
		TEST_METHOD(TestMethod1)
		{
			nums = {1,5 }, limit = 3;
			auto res = Solution().longestSubarray(nums, limit);
			AssertEx(1, res);
		}
		TEST_METHOD(TestMethod2)
		{
			nums = { 1,5 }, limit = 5;
			auto res = Solution().longestSubarray(nums, limit);
			AssertEx(2, res);
		}
		TEST_METHOD(TestMethod11)
		{
			nums = { 8, 2, 4, 7 }, limit = 4;
			auto res = Solution().longestSubarray(nums, limit);
			AssertEx(2, res);
		}
		TEST_METHOD(TestMethod12)
		{
			nums = { 10,1,2,4,7,2 }, limit = 5;
			auto res = Solution().longestSubarray(nums, limit);
			AssertEx(4, res);
		}
		TEST_METHOD(TestMethod13)
		{
			nums = { 4,2,2,2,4,4,2,2 }, limit = 0;
			auto res = Solution().longestSubarray(nums, limit);
			AssertEx(3, res);
		}
		TEST_METHOD(TestMethod14)
		{
			nums = { 2,2,2,4,4,2,5,5,5,5,5,2 }, limit = 2;
			auto res = Solution().longestSubarray(nums, limit);
			AssertEx(6, res);
		}
		TEST_METHOD(TestMethod15)
		{
			nums = { 24,12,71,33,5,87,10,11,3,58,2,97,97,36,32,35,15,80,24,45,38,9,22,21,33,68,22,85,35,83,92,38,59,90,42,64,61,15,4,40,50,44,54,25,34,14,33,94,66,27,78,56,3,29,3,51,19,5,93,21,58,91,65,87,55,70,29,81,89,67,58,29,68,84,4,51,87,74,42,85,81,55,8,95,39 }, limit = 87;
			auto res = Solution().longestSubarray(nums, limit);
			AssertEx(25, res);
		}
		TEST_METHOD(TestMethod16)
		{
			nums = { 7,40,10,10,40,39,96,21,54,73,33,17,2,72,5,76,28,73,59,22,100,91,80,66,5,49,26,45,13,27,74,87,56,76,25,64,14,86,50,38,65,64,3,42,79,52,37,3,21,26,42,73,18,44,55,28,35,87 }, limit = 63;
			auto res = Solution().longestSubarray(nums, limit);
			AssertEx(9, res);
		}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

Python 复制PDF中的页面

操作PDF文档时&#xff0c;复制其中的指定页面可以帮助我们从PDF文件中提取特定信息&#xff0c;如文本、图表或数据等&#xff0c;以便在其他文档中使用。复制PDF页面也可以实现在不同文件中提取页面&#xff0c;以创建一个新的综合文档。 本文将介绍如何使用Python 在同一文档…

Linux 计划任务

1.常见定时计划任务设置方式&#xff1a; at&#xff1a; 突发性的&#xff0c;临时决定只执行一次的任务。 crontab&#xff1a; 定时性的&#xff0c;每隔一定的周期就需要重复执行一次的命令。 用#date 为参考时间 1.1 at 计划任务的使用&#xff1a; 使用…

1.8 软件业务测试

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 概述2 方法3 测试策略4 案例分析 前言 在软件开发生命周期中&#xff0c;业务测试扮演着至关重要的角色。本文详细讲解了业务测试的定义、目的、方法以及测试策略。 本篇文章参…

Apache Iceberg Architecture—Iceberg 架构详解

Apache Iceberg Architecture Apache Iceberg 的架构可以分为三个主要层次&#xff1a;Iceberg Catalog、元数据层和数据层。 一、 Iceberg Catalog&#xff08;目录&#xff09; Iceberg Catalog 是 Iceberg 的顶层组件&#xff0c;负责管理所有 Iceberg 表的元数据和元数据操…

828华为云征文 | 智能监控新篇章,Prometheus如何在华为云Flexusx容器环境中大展身手

前言 在数字化转型的浪潮中&#xff0c;智能监控成为企业IT战略的关键环节。部署在华为云Flexus X实例上的Prometheus监控系统&#xff0c;凭借其卓越的性能与灵活性&#xff0c;正开启智能监控的新篇章。Flexus X实例以其强大的计算能力和灵活的资源管理&#xff0c;为Prometh…

I/O中断处理过程

中断优先级包括响应优先级和处理优先级&#xff0c;响应优先级由硬件线路或查询程序的查询顺序决定&#xff0c;不可动态改变。处理优先级可利用中断屏蔽技术动态调整&#xff0c;以实现多重中断。下面来看他们如何运用在中断处理过程中&#xff1a; 中断控制器位于CPU和外设之…

phpstudy简易使用

注意&#xff0c;本文所述的操作步骤均建立在电脑上已经完成php环境变量的配置与vscode的安装之上 、

万界星空科技数字孪生:解锁制造业未来,重塑智慧工厂新纪元

万界星空科技的数字孪生技术是一项创新的技术解决方案&#xff0c;它深度融合了工业大数据、物联网&#xff08;IoT&#xff09;、人工智能&#xff08;AI&#xff09;等先进技术&#xff0c;为制造业工厂提供了一个高度智能化、可视化的运营管理系统。以下是对万界星空科技数字…

EXEAL无法使用宏处理办法

在打开exeal的时候如果提示无法使用宏&#xff0c;或者不显示宏&#xff0c;可能是因为以下几个权限没有打开 1.随便打开一个exeal选择文件 2.选择更多里面的选项 3.选择信任中心里面的信任中心设置 4.信任中心宏设置启用所有宏 5.如果是网盘等其他路径的文件&#xff0c;点击…

leetcode-链表篇4

leetcode-2 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都…

VUE 开发——Node.js学习

一、认识Node.js Node.js是一个跨平台JavaScript运行环境&#xff0c;使开发者可以搭建服务器端的JavaScript应用程序 使用Node.js编写服务器端程序——编写数据接口、前端工程化&#xff1b; Node.js环境没有BOM和DOM&#xff1b; Node.js安装&#xff1a;下载node-v16.19…

C#基于SkiaSharp实现印章管理(10)

向PDF文件插入印章图片比之前实现的向图片文件插入印章麻烦得多。   最初的想法是使用PDF浏览控件在线打开PDF文件&#xff0c;然后在控件中实现鼠标移动时动态显示印章&#xff0c;点击鼠标时向当前PDF页面的鼠标点击位置插入图片。由于是.net 8的Winform项目&#xff0c;选…

数据结构 ——— C语言实现无哨兵位单向不循环链表

目录 前言 动态顺序表的缺陷 单链表的概念 单链表中节点的结构 单链表逻辑结构示意图​编辑 实现单链表前的准备工作 实现单链表 1. 定义节点的指针 2. 创建节点 3. 打印单链表中的所有数据 4. 在单链表头部插入数据 5. 在单链表尾部插入数据 6. 在单链表头部删除数…

HashMap的实现

Hash的最大容量为什么是2的30次方 问题 static final int *MAXIMUM_CAPACITY* 1 << 30; 回到题目&#xff0c;为什么会是2的30次幂&#xff0c;而不是2的31次幂呢&#xff1f; 首先&#xff1a;JAVA规定了该static final 类型的静态变量为int类型&#xff0c;至于为什…

神经网络在多分类问题中的应用

作者简介:热爱数据分析,学习Python、Stata、SPSS等统计语言的小高同学~个人主页:小高要坚强的博客当前专栏:Python之机器学习本文内容:神经网络在多分类问题中的应用作者“三要”格言:要坚强、要努力、要学习 目录 1. 引言 2.数据构造 3.划分数据集 4.神经网络实现多…

Stable Diffusion绘画 | 来训练属于自己的模型:素材处理与打标篇

纵观整个模型训练流程&#xff0c;图片素材准备和打标环节占据的分量比重&#xff0c;绝对超过60%。 上一篇分享了图片素材准备&#xff0c;这一篇&#xff0c;开始对准备好的图片素材进行处理了。 素材处理 我已经收集了 霉霉 的25张图片&#xff1a; 但是&#xff0c;发现…

4G模组SIM卡电路很简单,但也要注意这些坑

上次水SIM卡相关的文章&#xff0c;还是上一次&#xff1b; 上一篇文章里吹牛说&#xff0c;跟SIM卡相关的问题还有很多&#xff0c;目的是为下一篇文章埋下伏笔&#xff1b;伏笔埋是埋下了&#xff0c;但如果债老是不还&#xff0c;心里的石头就总悬着&#xff0c;搞不好老板…

黑名单系统源码全解无后门 +搭建教程

黑名单系统源码可以做骗子收录查询 搭建教程 1.我们先添加一个站点 2.PHP选择7.3 3.上传源码解压 4.导入数据库 5.配置数据库信息config.php https://download.csdn.net/download/huayula/89817619

2-3树(2-3 Tree):原理、常见算法及其应用

目录 引言 2-3树的基本概念 常见算法 查找节点 插入节点 删除节点 2-3树的应用场景 1. 文件系统目录管理 应用原理 场景描述 2. 字典编码 应用原理 场景描述 总结 优势对比 自平衡特性 灵活的节点结构 高效的操作性能 简单的实现 广泛的应用场景 数据一致…

【django】django项目使用https访问+ssl证书

目录 一、安装 django-sslserver 二、配置settings 三、启动项目测试 四、使用ssl证书 4.1 安装cryptography 4.2 生成证书代码 4.3 将生成的证书放到django项目根目录下 五、使用证书启动项目 5.1 本地测试启动 5.2 生产启动 六、生成docker镜像的dockerfile 七、…