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

Leetcode 58 | 附:滑动窗口题单 - 教程

1 题目

3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。注意 "bca" 和 "cab" 也是正确答案。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke"是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

2 代码实现

class Solution {
public:int lengthOfLongestSubstring(string s) {unordered_map window;int left = 0, right = 0;// 记录结果int res = 0;while (right < s.size()) {char c = s[right];right++;// 进行窗口内数据的一系列更新window[c]++;// 判断左侧窗口是否要收缩while (window[c] > 1) {char d = s[left];left++;// 进行窗口内数据的一系列更新window[d]--;}// 在这里更新答案res = max(res, right - left);}return res;}
};

滑动窗口解题框架(cpp)

class Solution {
public:int lengthOfLongestSubstring(string s) {unordered_map window;int left = 0, right = 0;// 记录结果int res = 0;while (right < s.size()) {char c = s[right];right++;// 进行窗口内数据的一系列更新window[c]++;// 判断左侧窗口是否要收缩while (window[c] > 1) {char d = s[left];left++;// 进行窗口内数据的一系列更新window[d]--;}// 在这里更新答案res = max(res, right - left);}return res;}
};

题解

1. 问题分析

题目要求找到字符串中无重复字符的最长子串长度。子串是连续的字符序列,因此需要保证窗口内的字符完全唯一,且尽可能长。

2. 滑动窗口框架适配

滑动窗口算法的核心是通过左右指针维护一个动态窗口,通过扩张和收缩窗口寻找最优解。本题中:

  • 窗口含义[left, right) 区间内的子串为当前候选的无重复子串
  • 扩张策略:右指针 right 不断右移,将新字符加入窗口
  • 收缩策略:当窗口中出现重复字符时,左指针 left 右移以移除重复字符
  • 数据结构:用 unordered_map<char, int> 记录窗口内字符的出现次数
3. 代码逐行解析
class Solution {
public:int lengthOfLongestSubstring(string s) {unordered_map window;  // 记录窗口内字符出现次数int left = 0, right = 0;          // 窗口左右边界(左闭右开)int res = 0;                      // 存储最大长度结果while (right < s.size()) {        // 右指针未越界时持续扩张窗口char c = s[right];            // 待加入窗口的字符right++;                      // 右指针右移,扩大窗口window[c]++;                  // 更新字符计数(扩张阶段的数据更新)// 当新加入的字符导致重复时,收缩左边界while (window[c] > 1) {       // 核心收缩条件:当前字符出现次数>1char d = s[left];         // 待移除窗口的字符left++;                   // 左指针右移,缩小窗口window[d]--;              // 更新字符计数(收缩阶段的数据更新)}// 此时窗口内无重复字符,计算当前窗口长度并更新最大值res = max(res, right - left);}return res;}
};
4. 关键逻辑解析
  • 窗口扩张right 从 0 移动到 s.size()-1,每次将字符 s[right] 加入窗口并更新计数
  • 窗口收缩:当 window[c] > 1 时(新加入的字符 c 重复),通过移动 left 移除字符 s[left] 并减少计数,直到 window[c] == 1
  • 结果更新:每次收缩完成后,窗口 [left, right) 一定是无重复子串,此时计算长度 right-left 并与历史最大值比较
5. 示例运行过程(以 "abcabcbb" 为例)
  • 初始状态:left=0, right=0, res=0
  • right=0:加入 'a',窗口 [0,1)res=1
  • right=1:加入 'b',窗口 [0,2)res=2
  • right=2:加入 'c',窗口 [0,3)res=3
  • right=3:加入 'a'(重复),收缩 left 到 1,窗口 [1,4)res 保持 3
  • 后续过程类似,最终最大长度为 3
6. 时间与空间复杂度
  • 时间复杂度:O (n),每个字符最多被 left 和 right 指针各访问一次
  • 空间复杂度:O (k),k 为字符集大小(最多 128 个 ASCII 字符)
7. 框架对应关系

完全符合滑动窗口伪码框架:

  • 用 unordered_map 实现 window 数据结构
  • 扩张阶段:right++ 并更新 window[c]++
  • 收缩阶段:left++ 并更新 window[d]--
  • 在收缩完成后更新结果

3 滑动窗口算法经典 LeetCode 题单(按难度 + 场景分类)

基础入门(理解窗口收缩与扩张逻辑)

  1. LeetCode 209. 长度最小的子数组:给定正整数数组和目标值,找和≥目标的长度最小的连续子数组,核心练 “窗口右扩找满足条件,左缩优化最小长度”。
  2. LeetCode 3. 无重复字符的最长子串:找字符串中不含重复字符的最长子串,核心练 “用哈希表记录字符位置,左边界跳转到重复字符下一位”。
  3. LeetCode 424. 替换后的最长重复字符:允许替换 k 个字符,找最长的重复字符子串,核心练 “窗口右扩统计最多重复字符,左缩控制替换次数≤k”。

中级进阶(窗口与哈希 / 计数结合)

  1. LeetCode 76. 最小覆盖子串:找包含目标字符串所有字符的最短子串,核心练 “哈希表记录目标字符需求,窗口收缩时校验是否仍满足覆盖条件”。
  2. LeetCode 438. 找到字符串中所有字母异位词:找字符串中所有目标串的字母异位词(字符相同顺序不同),核心练 “固定窗口长度,用计数数组比对字符频率”。
  3. LeetCode 567. 字符串的排列:判断目标串的排列是否是原串的子串,核心练 “固定窗口长度 = 目标串长度,计数数组快速比对频率”。
  4. LeetCode 904. 水果成篮:数组元素代表水果种类,最多选 2 种,找最长连续子数组,核心练 “用哈希表维护窗口内元素种类,左缩控制种类数≤2”。

高级拓展(多条件窗口 / 特殊场景)

  1. LeetCode 767. 重构字符串:判断能否重排字符串使相邻字符不同,核心练 “窗口内控制同一字符最多出现一次,结合贪心思想”。
  2. LeetCode 1004. 最大连续 1 的个数 III:允许翻转 k 个 0,找最长连续 1 的子数组,核心练 “窗口右扩统计 0 的个数,左缩控制 0 的个数≤k”。
  3. LeetCode 1234. 替换子串得到平衡字符串:字符串由 4 种字符组成,找最短子串替换后使 4 种字符数量相等,核心练 “反向思维,窗口外字符满足数量要求时收缩”。
http://www.jsqmd.com/news/105456/

相关文章:

  • 2025年高粘度篮式砂磨机生产厂家权威推荐榜单:篮式砂磨机/纳米篮式砂磨机/砂磨机源头厂家精选 - 品牌推荐官
  • 测试架构师的成长路径:从技术执行到质量战略的跨越
  • 北京十大知名律师事务所排行榜(2025-2026):权威测评靠谱解决方案名单 - 苏木2025
  • 鸿蒙 Electron 实战:跨端权限管控与鸿蒙身份认证集成方案
  • NGO-LSTM回归预测:北方苍鹰算法优化长短期记忆神经网络的数据预测模型
  • 告别图片管理噩梦:Note-Gen智能图床配置全攻略
  • 2025年钢质双包套门工厂权威推荐榜单:防火卷帘门/钢质门/钢木质防火门源头工厂精选 - 品牌推荐官
  • AI红队攻防实战环境搭建完全指南
  • AzerothCore魔兽世界服务器:3分钟搭建完整开发环境终极指南
  • 2025年国内十大抖音小店代运营公司权威推荐,云麦电商位居榜首 - 深度智识库
  • Python B站API终极指南:异步数据获取完整教程
  • Momo Code Sec Inspector Java 完整使用指南
  • 域控操作四:使用策略下发将域用户添加到本地管理员组
  • 构筑质量基石:测试团队管理的三重修炼
  • Citra模拟器终极指南:5步快速解决黑屏闪退问题
  • 【第61套】年度最难!Top1出炉!
  • apache echarts数据点重影或 Cannot read properties of undefined (reading type)错误问题
  • 2026年武汉定制整装家居优质展会推荐:国博门窗展、国博厨电卫浴展、武汉建材展、武汉建博会、智能木工机械展、第二届中国(武汉)整装定制家居暨建筑装饰材料博览会 - 海棠依旧大
  • 浏览器出现STATUS_STACK_BUFFER_OVERRUN错误代码,setting都无法打开
  • iOS防截屏
  • 如何在Windows上快速安装BiliBili-UWP:终极B站观看体验指南
  • ChatTTS-ui音色定制全攻略:从新手到专家的5个关键步骤
  • fail2ban安装及使用
  • 为什么越来越多的游戏公司选择EmotiVoice做角色配音?
  • 3分钟玩转Venera漫画阅读器:全平台安装配置与使用技巧分享
  • 广告定制行业排行与选择指南,电梯电子屏广告/应援广告/地铁站广告/电梯广告/社区广告/候车亭广告/明星应援广告广告采购选哪家 - 品牌推荐师
  • EmotiVoice语音合成历史版本回顾:从v0.1到v2.0的重大升级
  • 2025济宁婚纱摄影店推荐星级排名及甄选指南 - 提酒换清欢
  • Windows便携版Postman终极指南:打造高效移动开发环境
  • C/C++精品算法——双指针(1) - 实践