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

LeetCode 3.无重复字符的最长子串|Python题解(滑动窗口最优版)

LeetCode 3.无重复字符的最长子串|Python题解(滑动窗口最优版)

🔥 LeetCode力扣题解 | 难度:中等 | 标签:滑动窗口、双指针、哈希表、字符串、面试高频TOP

本篇题解严格适配CSDN原创排版与评分规则,纯标准Markdown格式,无多余锚点与格式冗余,代码可直接提交LeetCode,覆盖核心思路、逐行精讲、边界案例与易错提醒,复制即可一键发布,适配面试手撕与算法学习~


题目描述

给定一个字符串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 * 10^4(数据量较大,暴力解法会超时,必须优化)

  • s由英文字母、数字、符号和空格组成

  • 要求时间复杂度尽可能低,最优解法可达到线性时间


解题思路

本题是面试必考中等题,更是滑动窗口算法的入门经典题,属于字符串处理的高频题型。如果采用暴力枚举所有子串的解法,时间复杂度为O(n²),面对n≤5e4的数据量会直接超时,因此必须采用滑动窗口(双指针)+ 哈希表的最优解法,将时间复杂度降至O(n),线性遍历一次即可完成求解。

核心算法:滑动窗口(双指针)

滑动窗口的核心思想,是把字符串中的连续子串看作一个“窗口”,通过左右两个指针动态调整窗口的左右边界,保证窗口内始终无重复字符,全程只遍历字符串一次,效率拉满。

核心逻辑拆解

  1. 左指针:代表当前无重复子串的左边界,初始值为0;当窗口内出现重复字符时,右移左指针,收缩窗口,直至窗口内无重复。

  2. 右指针:代表当前无重复子串的右边界,负责不断向右扩展窗口,遍历整个字符串。

  3. 哈希表(字典):用于存储字符及其最后出现的下标位置,快速判断当前字符是否在窗口内重复,实现O(1)时间查询。

  4. 长度更新:每次扩展窗口后,计算当前窗口长度,实时更新最大长度值。

关键细节:左指针不能回退,只能向右移动,避免重复遍历,保证算法线性时间复杂度;哈希表存储的是字符最后出现的位置,而非是否出现,精准收缩窗口。


标准解法代码

严格遵循题目指定代码格式,滑动窗口最优实现,原地遍历、无额外空间浪费,注释详尽,适配新手理解与面试手撕,可直接复制提交LeetCode:

fromtypingimportListclassSolution:deflengthOfLongestSubstring(self,s:str)->int:# 哈希表:存储字符最后一次出现的索引,实现O(1)查询char_index={}# 左指针,初始指向窗口左边界left=0# 记录最长无重复子串长度max_len=0# 右指针遍历字符串,扩展窗口右边界forright,charinenumerate(s):# 字符重复,且在当前窗口内,收缩左边界ifcharinchar_indexandchar_index[char]>=left:left=char_index[char]+1# 更新当前字符的最后出现位置char_index[char]=right# 计算当前窗口长度,更新最大值current_len=right-left+1ifcurrent_len>max_len:max_len=current_lenreturnmax_len

代码逐行深度解析

1. 变量初始化

char_index={}left=0max_len=0
  • char_index:字典结构,键为字符串中的字符,值为该字符最后一次出现的下标,用于快速判断重复;

  • left:滑动窗口左指针,初始在字符串起始位置,标记当前无重复子串的左边界;

  • max_len:全局变量,记录遍历过程中遇到的最长无重复子串长度,初始为0。

2. 右指针遍历扩展窗口

forright,charinenumerate(s):

右指针right配合enumerate遍历字符串,每一步代表窗口向右扩展,逐个纳入新字符,全程仅遍历字符串一次,保证线性时间。

3. 重复字符判断与窗口收缩

ifcharinchar_indexandchar_index[char]>=left:left=char_index[char]+1
  • 判断条件一:字符已在哈希表中存在,说明之前出现过;

  • 判断条件二:该字符上次出现的位置在当前窗口内(下标 ≥ 左指针),说明当前窗口内重复;

  • 收缩逻辑:左指针直接跳到重复字符下标的下一位,跳过重复区域,保证窗口内无重复,左指针只右移不回退,避免无效遍历。

4. 更新字符位置与最大长度

char_index[char]=right current_len=right-left+1ifcurrent_len>max_len:max_len=current_len
  • 无论字符是否重复,都更新其最后出现的下标为当前右指针位置,保证哈希表数据最新;

  • 计算当前窗口长度:右指针 - 左指针 + 1(闭区间长度);

  • 实时对比更新最大长度,遍历完成后即为最终答案。

5. 结果返回

returnmax_len

遍历结束后,max_len存储的就是整个字符串中无重复字符的最长子串长度,直接返回即可。


示例运行过程演示

示例1:s = “abcabcbb”

  1. right=0(char=a):无重复,char_index[a]=0,窗口[0,0],len=1,max_len=1;

  2. right=1(char=b):无重复,char_index[b]=1,窗口[0,1],len=2,max_len=2;

  3. right=2(char=c):无重复,char_index[c]=2,窗口[0,2],len=3,max_len=3;

  4. right=3(char=a):a重复且在窗口内,left=1,char_index[a]=3,窗口[1,3],len=3,max_len不变;

  5. 后续遍历重复上述逻辑,窗口长度始终不超过3,最终max_len=3。

边界示例:空字符串/单字符

  • s=“”:无遍历,返回0,符合题意;

  • s=“z”:窗口[0,0],len=1,返回1,处理正确。


📊 算法复杂度分析

  • 时间复杂度O(n),n为字符串长度,左右指针各遍历字符串一次,哈希表查询与更新均为O(1),整体线性时间,完美适配n≤5e4大数据量,无超时风险;

  • 空间复杂度O(1)(常数级),哈希表存储的字符数量有限,最多为字符集大小(英文字母、数字、符号总数固定),并非随n线性增长,属于最优空间复杂度。

💡 解法对比(暴力VS滑动窗口)

暴力解法:枚举所有子串,判断是否重复,时间复杂度O(n²),大数据量下直接超时;

滑动窗口解法:一次遍历+哈希表快速查重,线性时间完成,是本题标准最优解,面试必写解法。


⚠️ 面试易错点与边界案例全覆盖

  • 边界1:空字符串s=""→ 返回0,特殊边界必须处理;

  • 边界2:全重复字符串s="bbbbb"→ 返回1;

  • 边界3:无重复字符串s="abcd"→ 返回字符串长度;

  • 边界4:含特殊字符/空格s="a b!a"→ 正常处理,哈希表支持所有字符类型;

  • 易错点1:混淆子串和子序列,忽略连续性;

  • 易错点2:左指针回退,导致时间复杂度升高;

  • 易错点3:未判断重复字符是否在当前窗口内,错误收缩窗口。

面试踩坑提醒:本题是滑动窗口入门必考题,核心得分点是线性时间复杂度+窗口不回退收缩,严禁写暴力解法;哈希表存储字符最后位置而非单纯标记存在,是优化关键!


📝 解题总结

无重复字符的最长子串是滑动窗口算法的标杆题型,核心思路是通过双指针动态维护无重复窗口,配合哈希表实现快速查重,兼顾时间与空间效率,代码简洁、逻辑清晰,适配所有边界场景。

掌握本题滑动窗口思想后,可快速举一反三,解决同类字符串子串、子数组问题,是面试手撕算法的高频考点,务必熟练掌握写法与核心逻辑。


原创算法题解,禁止转载~

如果对你有帮助,欢迎👍点赞、⭐收藏、💬评论交流,需要其他LeetCode题解也可以留言哦!

http://www.jsqmd.com/news/534702/

相关文章:

  • 从ELK迁移到阿里云SLS,我们团队一年省了XX万运维成本(实战复盘)
  • Misago:构建现代化社区论坛的全方位解决方案
  • YOLO X Layout开源镜像免配置部署:Gradio+ONNXRuntime开箱即用
  • 安装Claude Code 以及配置 Coding Plan 教程
  • Proteus仿真PCA9685踩坑实录:I2C波形正常但PWM无输出?手把手教你排查
  • 储能双向DCDC变换器的模型预测控制及仿真分析
  • 2026年电木板加工厂家推荐排行榜:绝缘电木板、耐高温电木板、治具及零配件定制切割加工专业实力解析 - 品牌企业推荐师(官方)
  • AI Agent 面试必问:设计一个写周报的 Agent,你会怎么答?
  • 利用快马平台快速构建copaw本地部署原型:十分钟搭建验证环境
  • 深度解析:oh-my-opencode智能代理架构设计与实现原理
  • ComfyUI-AnimateDiff-Evolved深度解析:掌握运动模块与上下文选项
  • 2026年玻纤板加工厂家推荐排行榜:定制/成品/绝缘件/治具/零切加工,耐高温绝缘玻纤板专业制造实力解析 - 品牌企业推荐师(官方)
  • nomic-embed-text-v2-moe部署案例:政务知识库多语种政策文件语义检索系统
  • ComfyUI工作流架构深度解析:从节点编排到企业级部署的完整技术栈
  • LeetCode 438.找到字符串中所有字母异位词|Python题解(滑动窗口最优版)
  • 单容水箱液位随动系统的模糊控制研究——基于‘化工与自动化仪表‘期刊论文复现
  • 2026年3月北京酒回收公司最新推荐:老酒回收、名酒回收、茅台酒回收、洋酒回收、红酒回收、五粮液酒回收公司选择指南 - 海棠依旧大
  • GitHub Actions:Python项目的CI/CD实践
  • 【20年架构师亲测】MCP插件安装成功率提升92%的7个关键操作(含SHA256校验与离线安装包获取路径)
  • 信奥赛网课水太深!家长选机构前,先看懂这4个坑
  • 离线音频转录全攻略:Buzz本地语音处理工具的高效应用指南
  • 老旧Mac图形性能重生计划:从卡顿到流畅的完整解决方案
  • 留言板
  • 嵌入式调试效率翻倍!玩转平头哥CDK的Watch窗口与串口打印(附实战技巧)
  • Solidity Patterns访问控制模式详解:构建安全的智能合约权限系统
  • 数据存储与运算-字面量
  • 接口测试总结
  • 7个步骤掌握DreamOmni2:多模态AI视觉创作工具从部署到精通
  • 清华大学提出统一多模态模型新突破:让AI同时学会“看“和“画“
  • Gemma-3-12b-it流式生成效果展示:上传图片+提问,实时回答惊艳案例