当前位置: 首页 > news >正文

[LC优选算法#2] 滑动窗口 | 长度最小的子数组 | 无重复字符的最长子串 | 最大连续1的个数

1. 算法思想

滑动窗口的本质是:维护一个满足条件的连续子数组/子串,通过移动左右边界来“滑动”这个窗口,从而找到最优解。滑动窗口是更加严格的双指针算法,大致思路都是用两个不回退的指针维护窗口。而且滑动窗口仅支持元素为正数的情况,不适用于负数或0(出窗口的时机无法确定)。

基本步骤:进窗口 -> 判断条件 -> 出窗口 -> 更新结果
(更新结果的时机因题而异)

2. 经典例题

2.1 ⻓度最⼩的⼦数组

⻓度最⼩的⼦数组

解题思路:

  1. 暴力解法O(N^2):从数组中的每个元素开始向后枚举,找出满足条件的最小长度。

显然,暴力解法中存在很多重复的计算。
例如下图,如果按照暴力枚举的方式统计,当2枚举结束后需要从3开始重新计算长度,但3之后的12都是没必要重新计数的。根据这一点,我们可以试着维护一个“窗口”来解决重复统计的耗时问题。

  1. 滑动窗口O(N):这个窗口满足内部所有元素之和小于target的条件。如果窗口内元素之和大于等于target,则更新结果,然后在逐个排除左边元素的同时,继续判断是否符合条件并继续更新结果;如果元素之和不满足条件,则加入新元素。

时间复杂度:由于维护窗口的left和right指针都是不回退的,最坏情况是两者分别遍历一次数组,因此总共耗时<= 2*N,时间复杂度为O(N)

classSolution{public:intminSubArrayLen(inttarget,vector<int>&nums){intn=nums.size();intlen=INT_MAX;intsum=0;for(intleft=0,right=0;right<n;right++){sum+=nums[right];while(sum>=target){len=min(len,right-left+1);sum-=nums[left];left++;}}returnlen==INT_MAX?0:len;}};

2.2 ⽆重复字符的最⻓⼦串

⽆重复字符的最⻓⼦串
解题思路:

  1. 暴力解法+哈希表O(N^2):从数组中的每个元素开始向后枚举,找出满足条件的最大长度。用哈希表统计出字符出现的频次,来判断什么时候子串出现了重复元素。

显然,研究对象依旧是一段连续的区间,以下图为例,在枚举完d后,没有必要以ea为起点重新向后枚举,因为重复元素a仍然在橙色区间中,枚举的长度只会更短。因此我们可以通过向右缩小窗口直至满足条件(绿色区间),然后继续让新元素进窗口。

2.滑动窗口+哈希表O(N):右端元素进⼊窗⼝的时候,哈希表统计这个字符的频次:

  • 如果这个字符出现的频次超过1,说明窗⼝内有重复元素,那么就从左侧开始划出窗⼝,直到这个元素的频次变为 1 ,然后再更新结果;
  • 如果小于1,说明当前窗⼝没有重复元素,可以直接更新结果。

时间复杂度:由于维护窗口的left和right指针都是不回退的,最坏情况是两者分别遍历一次数组,因此总共耗时<= 2*N,时间复杂度为O(N)

classSolution{public:intlengthOfLongestSubstring(string s){intleft=0;intright=0;intn=s.size();intmaxlen=0;vector<int>hash(128,0);//128个字符,用数组模拟哈希表while(right<n){hash[s[right]]++;while(hash[s[right]]==2)//加1在前判断在后则为2{hash[s[left++]]--;}maxlen=max(maxlen,right-left+1);right++;}returnmaxlen;}};

2.3 最⼤连续 1 的个数 III

最⼤连续 1 的个数 III

解题思路:

可以翻转最多 k 个 0 ,转化为找一个包含 k 个 0的最长区间。

  1. 暴力解法O(N^2):以每个元素为起点,依次向后找最长的子数组。

题目包含连续区间,考虑用滑动窗口思想解决:

  1. 滑动窗口O(N):窗口内部存放有k个0的连续子串,以子串中0的个数为判断条件,维护窗口,超出k个0则停止更新,left指针左移;不够k个0则right指针右移,更新窗口。
classSolution{public:intlongestOnes(vector<int>&nums,intk){intleft=0;intright=0;intzerocnt=0;intlen=0;intn=nums.size();while(right<n){if(nums[right]==0){zerocnt++;}while(zerocnt>k){if(nums[left++]==0){zero--;}}len=max(len,right-left+1);right++;}returnlen;}};

// 本期内容就到这里,如果对你有帮助,请三连支持!我是青云,我们下期见^_~

http://www.rkmt.cn/news/1496707.html

相关文章:

  • 深圳民办高中办学硬实力与口碑家长疑问解答 - 奔跑123
  • N_m3u8DL-RE:跨平台流媒体下载器的技术深度解析
  • 对外经济贸易大学考研辅导班正规机构,全维度榜单推荐 - 推荐评测师
  • 人工智能专业术语详解(E)
  • Java IO 流文件复制全解:字符缓冲流 vs 字节缓冲流
  • Java程序设计(第3版)第四章——继承的调用
  • 2026 三明厨卫屋面地下室漏水瓷砖空鼓测评:吉修匠 99.8 分五星榜首 - 吉修匠
  • 论文精读:喀斯特山地流域耕地流转的时空演变与地形梯度效应——以贵州南北盘江流域为例
  • HAMi 源码阅读笔记 01:HAMi调度简介
  • 金融行业常用哪些数据分析模型?风控、授信、客户分层框架汇总
  • 基础知识(从零开始学C语言)
  • Tcl语言:file命令的使用方式
  • 【MATLAB】基于模型预测控制的车辆圆轨迹跟踪方法研究
  • ngx_signal_worker_processes
  • 北京看守所律师事务所:驻所法律服务与常规代理有何本质区别? - 品牌2026
  • 丽水缙云县黄金回收指南:避开陷阱,多拿上千元 - 专业黄金回收
  • 细说KISS、YAGNI原则
  • 论文精读:基于GIS与地理探测器的西南喀斯特石漠化空间分布及驱动因子分析
  • 制造业领域:2026年值得关注的手推式/驾驶式/全自动工业扫地机制造商 - 企业推荐官【官方】
  • 2026义乌UV双喷服务机构整理推荐 - 奔跑123
  • 通诚无忧-通辽信息港信息平台运营策略:打造用户喜爱的通辽市本地服务社区
  • Playwright视觉比较(图片比对测试)
  • 第76篇 | HarmonyOS 保险箱详情页:私密照片如何浏览、恢复和导出
  • Kotlin单表达式函数在安卓开发中的精简艺术
  • 手把手教你用MATLAB复现圆柱绕流POD分解:从Brunton的代码到自己的流场图
  • AgentWatch MCP 服务说明文档
  • 基于 LlamaIndex + DeepSeek + Streamlit 搭建智能问答系统
  • 2026最新渭南市黄金回收价格一览表 回收避坑攻略靠谱商家推荐 - 余生黄金回收
  • UVM源码探秘:start_item的sequencer参数怎么用?解锁更灵活的sequence驱动方式
  • 10kV配网故障识别:波形分析全攻略