解密单调队列:滑动窗口最值优化技巧
单调队列这一字眼进一步理解明显的单调性基于近期复刷的单调队列题目形如经典的模版题目P1886 【模板】单调队列 / 滑动窗口 以及对此进行的变式P1714 切蛋糕 ,P1638 逛画展P1886的模版题让我重新回顾了一下如何维护一个单调区间在这道题中维护单调区间的意义是为了保持其当前窗口的最大值为队首队首则是依次为更小的值这样的区间有一个特点如果当我们队首因为离开了窗口内范围而跳脱此时新队首会成为新的最大而当我们窗口进行移动时如果新来的值的大小有点大我们就依次对队尾元素进行比较后让他们pop()毕竟他们这么小已经没有可能作为当前窗口的最大值了。我们找每个时期的最小值也是同样的道理。这样的题目常用双端队列deque进行解答对于我这种初学者来说单调队列的队列一词感觉有所误导因为初学者对队列的印象大都停留在先进先出的效果单调区间更感觉符合我们想要的效果感觉有点抽象。单调队列单调栈滑动窗口int n,k; cin n k; vectorinta(n1); vectorintans_mx; vectorintans_mi; dequeintmx; dequeintmi; for(int i1;in;i) { cin a[i]; } for(int i1;in;i) { while(!mx.empty()i-kmx.front()) { mx.pop_front(); } while(!mx.empty()a[mx.back()]a[i]) { mx.pop_back(); } while(!mi.empty()i-kmi.front()) { mi.pop_front(); } while(!mi.empty()a[mi.back()]a[i]) { mi.pop_back(); } mx.push_back(i); mi.push_back(i); if(ik) { ans_mx.push_back(a[mx.front()]); ans_mi.push_back(a[mi.front()]); } }核心代码其实就几行但在干一件有点难说清楚的事我捋捋首先这题让我们判断窗口大小固定为k自发地向右移动的过程这个窗口内的最大或最小值我去那我直接每次移动都直接暴力检索最值不行不行这样直接TLE。从正解来理解我们在做一个这样的事情假如当前的窗口是一个从大到小的区间从左往右我们可以发现这样单调的区间每次最大的最左的那个数因为离开了窗口的大小范围pop紧接着因为区间是单调的所以下一个数就是最大的值但是如果此时下一个进入窗口的数明显的打乱了单调性来了个相当大的值怎么办这个值会影响其他满足前一时刻单调性的值成为最大值的可能性所以我们需要把这一时刻区间内不再可能成为最大值的数据删除重新让这个区间的单调性保持从大到小。隐藏的单调性接下来我们看P1714切蛋糕一题这一题的解法还是核心单调队列但这不一样的是单调性表现需要用前缀和看出来简单说下题目意思意思就是类比上题这题我们也当做一个滑动窗口然后我们需要在窗口里找到和最大的区间注意区间是连续的固定区间的最大连续子段和当然暴力依然TLE我们需要用单调队列的方法降低到O(n)int n,m; cin n m; vectorinta(n1); vectorintsum(n1,0); dequeintq; for(int i1;in;i) { cin a[i]; sum[i]sum[i-1]a[i]; } q.push_back(0); int ans-LLONG_MAX; for(int i1;in;i) { while(!q.empty()i-mq.front()) { q.pop_front(); } ansmax(ans,sum[i]-sum[q.front()]); while(!q.empty()sum[q.back()]sum[i]) { q.pop_back(); } q.push_back(i); } cout ans endl;我们依旧从代码入手很明显我们可以发现核心代码与模版题目的及其相似都是在对头与尾进行操作sum[q.back()]sum[i]这一步是整个单调性维护的核心。其实这道题的核心跟上一题是一样的我们都要保持队首的一个最值状态因为我们要最大话sum[i]-sum[q.front()]所以我们需要让sum[q.front()]的值最小化那我们有更小的sum选手不就应该淘汰前边没用的家伙吗。难发现的单调性队列再看P1638逛画展这一道并没有单调性但跟单调队列的思想相似的一道题我看了题解做法多是双指针学完单调队列后发现可行便写了下来。题目意思让你在n大小的数组里用最小的区间包含1-m的数的左端点跟右端点。int n,m; cin n m; vectorinta(n1); vectorintnum(m1,0); dequeintq; for(int i1;in;i) { cin a[i]; } int k0; int ansLLONG_MAX; int l1,rn; for(int i1;in;i) { q.push_back(i); num[a[i]]; if(num[a[i]]1)k; while(!q.empty()km) { if(ansq.size()) { lq.front(); rq.back(); ansq.size(); } num[a[q.front()]]--; if(num[a[q.front()]]0)k--; q.pop_front(); } } cout l r;这里不一样的是对队列操作并没有对队尾进行pop而是与循环次数同时进行push所以直接用queue就行思路就是我们从最左段开始扩展我们的区间大小等到区间内包含所有数时用桶数组进行计数让队首进行pop直到区间内不包含所有数时继续让数据进行入队这个核心思想其实跟双指针是一样的。更正我发现这一题我的代码其实就是普通队列加上双指针的思想双端队列的写法应该是在队首跟队尾相同时将队头排出使得整个队伍的长度尽可能的小。单调队列的写法所维护的是队首在队内出现的次数为1。总结单调队列的题目能从题目大致看出滑动窗口最值这样的搭配一般优先考虑优先队列我们来回顾一下第一道明显单调性的单调队列很明显我们是通过维护一个单调的队列让队首保持一个最值的状态从而显现出我们的每个时期的答案。再看下一道隐藏单调性的题目我们用的是一个前缀和的作差形式计算区间和进而有sum[i]-sum[q.front()]这一重要的步骤而为了使答案最大化我们需要时减数最小化所以sum[q.back()]如果遇到了更小的sum[i]那么这个队尾就会被淘汰新的队尾更加合适。所以简而言之对于单调队列的题目我们需从其最值的计算方式入手找到单调性关系一般为队尾与新入队的数作比较。更正补充对于我对单调队列的题目没有一个清晰完整的流程特来补充1.俩个单调队列的题目都是首先我们发现了其是一个滑动窗口然后题目要求某最值2.我们把队首作为最小或最大状态进行保持单调性的后移动按这种方法来很轻而易举的就能把模版题目做出来但前缀和变式不行前缀和变式通过固定i在窗口内找到一个最小sum[j]使得sum[i]-sum[j]最大化所以我们要维护的队列就变成了sum[j]的单调递增队列

相关新闻

MSPM0 DMA控制器:从原理到实战,打造高性能嵌入式数据搬运系统

MSPM0 DMA控制器:从原理到实战,打造高性能嵌入式数据搬运系统

1. DMA控制器:嵌入式系统的“数据搬运工”与性能倍增器在嵌入式系统开发中,CPU常常被各种琐碎的数据搬运任务所拖累。想象一下,你的主控芯片就像一个忙碌的厨师,不仅要炒菜(执行核心算法),还要不…

2026/7/24 19:26:24阅读更多 →
DeepSeek    LeetCode 3686. 稳定子序列的数量 Python3实现

DeepSeek LeetCode 3686. 稳定子序列的数量 Python3实现

python class Solution:def countStableSubsequences(self, nums: List[int]) -> int:MOD 10**9 7# dp[p][c]:# p: 0偶数, 1奇数# c: 0末尾连续长度为1, 1末尾连续长度为2dp [[0, 0] for _ in range(2)]for num in nums:p num & 1 # 当前元素的奇偶性q p ^ 1 #…

2026/7/24 19:24:24阅读更多 →
实时位置服务的架构设计:GeoHash 索引与空间查询优化

实时位置服务的架构设计:GeoHash 索引与空间查询优化

实时位置服务的架构设计:GeoHash 索引与空间查询优化 一、深度引言与场景痛点:当百万司机同时在移动 打车软件的核心功能是"找到附近的司机"。用数据库的朴素写法是: SELECT * FROM drivers WHERE lat BETWEEN ? AND ? AND lng B…

2026/7/24 19:24:24阅读更多 →
终极本地图片搜索方案:基于.NET 10的千万级图库秒级检索工具完全指南

终极本地图片搜索方案:基于.NET 10的千万级图库秒级检索工具完全指南

终极本地图片搜索方案:基于.NET 10的千万级图库秒级检索工具完全指南 【免费下载链接】ImageSearch 基于.NET10的本地硬盘千万级图库以图搜图案例Demo和图片exif信息移除小工具分享 项目地址: https://gitcode.com/gh_mirrors/im/ImageSearch 你是否曾面对硬…

2026/7/24 20:58:41阅读更多 →
OpenClaw Cron:AI驱动的动态定时任务调度系统实践

OpenClaw Cron:AI驱动的动态定时任务调度系统实践

1. 项目背景与核心价值去年在开发智能客服系统时,我遇到了一个典型问题:每天凌晨需要自动生成前一天的客户服务报告,但传统定时任务框架无法适应动态变化的业务需求。比如双十一期间需要每小时生成一次报告,而平时只需要每日汇总。…

2026/7/24 20:58:41阅读更多 →
HarmonyOS ArkTS 实战:打造高评分音乐播放器与歌单管理应用

HarmonyOS ArkTS 实战:打造高评分音乐播放器与歌单管理应用

项目背景与效果 随着鸿蒙生态的日益壮大,使用 ArkTS 开发原生应用成为开发者必备技能。本项目从零开始,手把手带你实现一款功能完整、界面精美的音乐播放器与歌单管理应用,涵盖播放控制、进度条、歌词同步等核心能力,可直接运行于…

2026/7/24 20:58:41阅读更多 →
OpenAI Codex实战指南:从代码生成到编程思维助手的进阶用法

OpenAI Codex实战指南:从代码生成到编程思维助手的进阶用法

那天下午,我盯着一个半成品的 Python 脚本,它需要调用几个不同的天气 API,把数据清洗后存进数据库。每个 API 的返回格式都不一样,有的嵌套三层 JSON,有的用奇怪的字段名。我写了半小时,大部分时间都在翻文…

2026/7/24 20:58:41阅读更多 →
基于AI大模型的股票智能分析系统:零成本自动化投资决策解决方案

基于AI大模型的股票智能分析系统:零成本自动化投资决策解决方案

基于AI大模型的股票智能分析系统:零成本自动化投资决策解决方案 在当今信息爆炸的股票市场中,投资者面临着海量数据难以消化、分析效率低下、决策依据不足等核心痛点。GitHub_Trending/da/daily_stock_analysis项目提供了一套完整的AI驱动解决方案&…

2026/7/24 20:58:41阅读更多 →
daily_stock_analysis 数据源与策略配置实战手册:打造个性化智能分析系统

daily_stock_analysis 数据源与策略配置实战手册:打造个性化智能分析系统

daily_stock_analysis 数据源与策略配置实战手册:打造个性化智能分析系统 daily_stock_analysis 是一款基于 LLM 的股票智能分析系统,为投资者提供多数据源行情、实时新闻、决策看板和自动推送功能。本文将指导您如何通过自定义配置,构建适合…

2026/7/24 20:56:41阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 0:58:53阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 0:58:53阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 0:58:53阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:06阅读更多 →
【LeetCode 54】螺旋矩阵

【LeetCode 54】螺旋矩阵

问题描述: 解法: 1、模拟(参考自【LeetCode 54】螺旋矩阵-CSDN博客) int *spiralOrder(int **matrix, int matrixSize, int *matrixColSize, int *returnSize) {static const int dirs[4][2] {{0, 1}, {1, 0}, {0, -1}, {-1, …

2026/7/24 0:00:06阅读更多 →
2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

知春路不相信模型领先今年WAIC大会,昔日AI六小龙来了五家,分别是Kimi、阶跃星辰、Minimax、百川智能、零一万物。连放弃基模的百川和零一万物都来了,唯一缺席的竟是近几个月来风光无限的智谱。(DeepSeek一直不参加)WAI…

2026/7/24 0:00:06阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/23 22:58:43阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/24 19:00:40阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/24 19:00:40阅读更多 →