【题目讲解】 算法系列之定长类滑动窗口解析(上)
目录前言Part1. 标准滑动窗口Part1.1. 定长子串中元音的最大数目Part1.2. 子数组的最大平均数Part2. 滑动窗口哈希表Part2.1. 长度为K子数组中的最大和Part3. 转化类滑动窗口Part3.1. 得到K个黑块的最少涂色次数Part3.2. 重新安排会议得到最多空闲时间Part4. 总结Part5. 结语前言滑动窗口作为经典的算法之一他可以有效地简化遍历这个操作的时间复杂度。接下来跟随小编的步伐来看看这个算法具体使用吧。lets go!!!!!!!!!Part1. 标准滑动窗口我们先来看标准的滑动窗口的实施理解这个基础才可以更好的去结合一些花里胡哨的东西。我们来看看吧Part1.1. 定长子串中元音的最大数目题目链接1456. 定长子串中元音的最大数目 - 力扣LeetCode我们首先想到的方法就是把这个字符串中长度为三的串全部处理一遍得到元音数目的最大值但这样对于这个字符串每个字符都几乎要遍历三次有没有一次遍历就可以解决问题的方法有的那就是滑动窗口我们来看这里的关键就在于保留了之前遍历的成果即1~2中字符是否为元音的信息只改变最少要改变的即必须要知道3处的字符的信息才能继续遍历同时要满足题目的条件即m定长也就是我没必要删去0处字符曾经的影响即他如果是个元音字符我们就要num--来消除他的影响使得m在逻辑上的长度不变我们在用一个max_num来记录全局的最大值作为我们的最终答案我们来看代码class Solution { public: bool is_vowel(char a)//判断是否为元音字符 { if(aa||ae||ai||ao||au) { return true; } return false; } int maxVowels(string s, int k) { int max_num0; int num0; for(int i0;ik;i)//初始化窗口 算出num的初始值 { if(is_vowel(s[i])) { num; } } max_numnum;//初始化全局最大值 int left0;//窗口的最左边 指向要抛弃的元素的下标 int rightk;//窗口的最右边 指向要新增的元素的下标 while(rights.size()) { if(is_vowel(s[left]))//如果是元音 就要去除他造成的影响 { num--; } if(is_vowel(s[right]))//看看新增的字符是否为元音 是就加上 { num; } if(nummax_num)//更新全局最大值 { max_numnum; } left;//窗口滑动到下一个要抛弃的元素 right;//窗口滑动到下一个要新增的元素 } return max_num; } };这就是标准滑动窗口的实施了我们再看一题来巩固一下吧。Part1.2. 子数组的最大平均数题目链接643. 子数组最大平均数 I - 力扣LeetCode直接来看代码class Solution { public: double findMaxAverage(vectorint nums, int k) { double num0;//记录窗口内所有元素的和由于窗口的长度是一定的 我们只要记录所有元素和就可以知道平均数了 double max_average0; for(int i0;ik;i) { numnums[i];//初始化 } max_averagenum/k;//初始化记录全局最大平均数的变量 int left0;//指向要抛弃的元素 int rightk;//指向要新增的元素 while(rightnums.size()) { numnums[right];//加上后面新增的元素的值 num-nums[left];//这里去除前面的影响就是删去num中前面元素的值 if(num/kmax_average) { max_averagenum/k;//更新最值 } right;//移动窗口 left; } return max_average; } };这就是标准滑动窗口我们来看它的一个变种即与哈希表结合。Part2. 滑动窗口哈希表这也算是一种经典的结合即我们在处理的过程中不是记录这些数的总数值什么的而是其出现的频率。我们结合题目来具体看看吧Part2.1. 长度为K子数组中的最大和题目链接2461. 长度为 K 子数组中的最大和 - 力扣LeetCode这道题在之前的基础上还要求我们子数组中所有元素都不能相同这个数组的和才能算是有效的这就需要我们结合哈希思想来解决即我们记录每个元素出现的频率只有每个元素出现都恰好为一时这个数组的和才能参与到最大数组和的更新中我们来看代码class Solution { public: int is_same(vectorshort hash,int i,int a)//根据元素的频率 返回不同的值 { int return_num0;//return_num先初始化为0 if(hash[i]1)//如果此时频率恰好为1 又由于我们一定会对其改变 所以我们要收回之前这个元素出现的频率恰好为一时加的1 return_num-1;//更新为-1 if(a1)//频率处理 hash[i]; else hash[i]--; if(hash[i]1)//如果频率恰好为一 则要返回1 return_num1; return return_num; } long long maximumSubarraySum(vectorint nums, int k) { int minINT_MAX; int maxINT_MIN; for(int i0;inums.size();i) { if(nums[i]max) maxnums[i]; if(nums[i]min) minnums[i]; } vectorshort hash(max-min1,0);//初始化哈希 int dif_num0;//记录子数组中不同元素的数目即dif_numm时 这个数组和有效 long long max_num0;//记录全局最大值 long long num0;//记录过程数组和 int left0; int rightk; for(int i0;ik;i)//初始化num dif_num { numnums[i]; dif_numis_same(hash,nums[i]-min,1); } if(dif_numk)//当dif_numk时 更新最值 { max_numnum; } while(rightnums.size()) { num-nums[left];//去除 numnums[right];//新增 dif_numis_same(hash,nums[left]-min,2);//去除 dif_numis_same(hash,nums[right]-min,1);//新增 if(dif_numkmax_numnum)//当两个条件都满足时 更新最值 { max_numnum; } left;//移动滑窗 right; } return max_num; } };这种题就是在数据的处理上用到了哈希表结合常规知识我们来看下一题Part3. 转化类滑动窗口有时候我们这个题目不是明显的说这个子数组是明显的我们就需要转化问题变成滑动窗口我们来看Part3.1. 得到K个黑块的最少涂色次数题目链接2379. 得到 K 个黑块的最少涂色次数 - 力扣LeetCode我们来看图解我们来看代码class Solution { public: int is_white(char c)//判断是不是白块 { if(cW) return 1; else return 0; } int minimumRecolors(string blocks, int k) { int left0; int rightk; int num0; for(int i0;ik;i) { numis_black(blocks[i]);//初始化num } int minnum;//初始化全局最小值 while(rightblocks.size()) { num-is_black(blocks[left]);//去除前面的 numis_black(blocks[right]);//增加后面的 if(nummin) { minnum;//更新最小值 } } return min; } };这样我们就解决了这题很多题他不是明着来滑动窗口的他是潜藏在其中的在下一题也有体现我们来看Part3.2. 重新安排会议得到最多空闲时间题目链接3439. 重新安排会议得到最多空余时间 I - 力扣LeetCode我们来看图解我们来看代码class Solution { public: int maxFreeTime(int eventTime, int k, vectorint startTime, vectorint endTime) { vectorint arr; if(startTime[0]!0) arr.push_back(startTime[0]-0); for(int i1;istartTime.size();i) { arr.push_back(startTime[i]-endTime[i-1]);//得到空闲时间数组 } if(eventTime!endTime[endTime.size()-1]) arr.push_back(eventTime-endTime[endTime.size()-1]); int sizek1;//得到窗口长度 int num0;//下面就是正常求最值 int max_num0; for(int i0;isize;i) { if(iarr.size()) return num; numarr[i]; } max_numnum; int left0; int rightk1; while(rightarr.size()) { num-arr[left]; numarr[right]; if(nummax_num) max_numnum; } return max_num; } };经过转化我们将原本离散的场景整合为连续的场景从而可以使用滑动窗口来解决。Part4. 总结滑动窗口本质上还是一个工具主要就是帮我们解决在连续的条件下直接遍历的时间复杂度过高的场景。它可以大大简化时间复杂度用一句话总结就是“拆东墙补西墙”保留之前花费时间得来的成果改变需要改变的。其实通过上面的代码我们也可以发现一套代码的通用模板我们来看int main() { { ;//定义变量 } { ;//初始化变量将窗口展开 } { ;//看条件是否初始化全局类型的值 } while(){ { ;//去除左边 } { ;//新增右边 } { ;//更新最值 } { ;//移动窗口 } } //。。。。。。。 }Part5. 结语相信通过上面几道题的讲解大家已经对这个算法有了一定程度的认识后续小编还会推出下篇更加深化滑动窗口的相关知识敬请期待~~希望这篇博客可以给大家带来帮助。最后祝大家可以春风得意马蹄疾一日看尽长安花最后的最后要是觉得本文还可以的话可以点点赞关注小编一波谢谢大家~

相关新闻

抖音账号与手机号关联验证:合规路径、技术实现与风险规避指南

抖音账号与手机号关联验证:合规路径、技术实现与风险规避指南

1. 项目概述与核心需求解析最近在和一些做用户运营、市场调研的朋友聊天时,发现一个挺有意思的需求:他们手头有一些抖音账号,想知道这些账号背后有没有绑定手机号,或者更进一步,想验证某个手机号是否注册了抖音。这个需…

2026/6/26 3:22:35阅读更多 →
分层设计的记忆系统

分层设计的记忆系统

Hermes Agent 打破了传统的全量存储模式,它借鉴 CPU 缓存的设计思想打造出了一个分层记忆系统,这一解决方案在一定程度上缓解了由 OpenClaw 在跨会话记忆方面的缺陷所带来的一系列问题,为 Agent 应用的持久记忆机制提供了一种更稳定的工程实现…

2026/6/26 3:22:35阅读更多 →
AACT Portable:便携式Oracle数据库测试环境搭建与实战指南

AACT Portable:便携式Oracle数据库测试环境搭建与实战指南

1. 项目概述:什么是AACT Portable?如果你是一名数据库管理员、软件测试工程师,或者经常需要在本机搭建一个轻量级的Oracle数据库环境用于学习、开发或测试,那么你一定对Oracle那庞大的安装包、复杂的配置过程以及严格的许可协议感…

2026/6/26 3:17:35阅读更多 →
前Zod作者新开源项目Nub:性能快、兼容性强,能否打破Node.js工具碎片化困局?

前Zod作者新开源项目Nub:性能快、兼容性强,能否打破Node.js工具碎片化困局?

前Zod作者推出Nub,发布一天登Hacker News首页前Zod作者、前Bun团队成员Colin McDonnell推出全新开源项目,发布仅一天即登上Hacker News首页,收获近2000 Star。不打算「杀死」任何东西的野心项目是什么?2026年6月24日,名…

2026/6/26 4:22:40阅读更多 →
马鞍山栈板工厂怎么选?看完这篇不纠结

马鞍山栈板工厂怎么选?看完这篇不纠结

在工业物流与仓储运输中,木托盘(或称栈板)是不可或缺的基础工具。马鞍山及周边地区制造业密集,选择合适的托盘供应商直接关系到物流效率与成本控制。面对市场上众多的工厂,如何避免踩坑、选到真正靠谱的合作伙伴&#…

2026/6/26 4:22:40阅读更多 →
2026流年运势批量推演怎么做?玄易AI命理软件测评

2026流年运势批量推演怎么做?玄易AI命理软件测评

2026流年运势批量推演怎么做?玄易AI命理软件测评很多人第一次接触命理软件,是为了查看个人运势;但真正用得多以后,会发现重复操作才是最消耗时间的部分。比如做流年运势批量推演时,用户往往要反复输入出生信息、切换年…

2026/6/26 4:22:40阅读更多 →
向量空间 JBoltAI TokUI 的定位与设计背景

向量空间 JBoltAI TokUI 的定位与设计背景

向量空间 JBoltAI 推出的 TokUI,是面向 AI 应用场景打造的流式 UI 描述与渲染框架,核心围绕大模型的文本输出特性,重构 UI 的描述、传输与渲染全链路。以下从产品定位与设计背景两个维度,对 TokUI 进行具体说明。一、TokUI 是什么…

2026/6/26 4:22:40阅读更多 →
托管式 Agent 成为主流方向

托管式 Agent 成为主流方向

AI Agent 正从技术概念快步走向生产应用。然而,当开发者试图将原型推向生产环境时往往发现:从"跑通 Demo"到"稳定上线",每一步都是对基础设施的真实考验。更聪明的模型解决不了这道鸿沟——企业真正需要的,是…

2026/6/26 4:22:40阅读更多 →
一句话生成漫剧、漫画、小说:AI全模态创作平台实测,创作效率提升10倍

一句话生成漫剧、漫画、小说:AI全模态创作平台实测,创作效率提升10倍

前言 上篇文章我拆解了一句话生成小说的全流程,很多读者留言问:能不能直接出漫画?能不能自动合成漫剧? 答案是:能。同一个平台,同一套工作流。 极栈创作平台(极栈创作平台 - JZCloud&#xf…

2026/6/26 4:17:40阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/25 9:39:54阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/26 4:15:25阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/25 9:01:34阅读更多 →
HPE (慧与) 服务器专用 ESXi 9 全套官方定制资源详解 + 完整部署升级教程

HPE (慧与) 服务器专用 ESXi 9 全套官方定制资源详解 + 完整部署升级教程

一、前言:企业运维痛点与资源价值自博通收购 VMware 之后,原 VMware 公开免费下载渠道全面关闭,企业运维人员想要获取适配 HPE 慧与服务器的 ESXi 9 原厂镜像,必须注册博通账号、绑定有效授权才能下载,无授权账号无法获…

2026/6/26 0:02:15阅读更多 →
Kotlin的@JvmStatic与@JvmField:与Java互操作的注解

Kotlin的@JvmStatic与@JvmField:与Java互操作的注解

Kotlin作为一门现代编程语言,与Java的互操作性一直是其核心优势之一。为了让Kotlin代码能够无缝对接Java,Kotlin提供了多种注解来优化互操作体验,其中JvmStatic和JvmField是两个关键注解。它们分别用于解决静态成员和字段在Java中的访问问题&…

2026/6/26 0:02:15阅读更多 →
深入解析musl libc中的mmap实现源码

深入解析musl libc中的mmap实现源码

最近在阅读musl libc源码时,发现其mmap的实现非常精妙,特分享给大家。 一、代码整体结构 这段代码实现了__mmap函数,并通过weak_alias导出为mmap。这是典型的musl libc风格——提供弱符号以便用户可以重写。 weak_alias(__mmap, mmap); 二…

2026/6/26 0:02:15阅读更多 →