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

LeetCode 第3题 无重复字符的最长子串(滑动窗口(双指针)+ HashSet)

一、核心算法思想

采用滑动窗口(双指针)+ HashSet,时间复杂度 \(O(n)\)。

  1. 定义窗口区间 \([i,rk]\):代表当前正在考察、无重复字符的连续子串;
  2. i:窗口左边界(外层循环遍历);rk:窗口右边界,只会向右移动,不回退
  3. HashSet 集合occ:实时保存当前窗口内部所有字符,快速判断字符是否重复;
  4. 流程:
    • 左边界i右移时,将移出窗口的字符从集合删除;
    • 在不重复前提下,尽可能向右扩张右边界 rk;
    • 每次扩张停止后,计算窗口长度,更新全局最长长度答案ans

区分概念:子串必须连续;子序列可以不连续。

二、完整带注释代码

class Solution { public int lengthOfLongestSubstring(String s) { // occ = occurrence,存储当前滑动窗口内的字符 Set<Character> occ = new HashSet<>(); int n = s.length(); int rk = -1, ans = 0; // rk右指针初始-1;ans=answer保存最终结果 for(int i = 0; i < n; i++){ if(i != 0){ // 左边界右移,把离开窗口的字符移除集合 occ.remove(s.charAt(i-1)); } // 右边界持续扩张:下一个字符不越界、且窗口不存在该字符 while(rk + 1 < n && !occ.contains(s.charAt(rk + 1))){ occ.add(s.charAt(rk + 1)); rk++; } // 更新最长子串长度 ans = Math.max(ans, rk - i + 1); } return ans; } }

三、实例运行推演

输入:s = "abcabcbb"

i (左边界)操作rk窗口\([i,rk]\)occ 集合当前窗口长度ans 最大值
i=0i=0 无需 remove;持续右扩 rk2[0,2]{a,b,c}3ans=3
i=1删除 s [0] 字符 a;右扩 rk3[1,3]{b,c,a}3ans=3
i=2删除 s [1] 字符 b;右扩 rk4[2,4]{c,a,b}3ans=3
i=3删除 s [2] 字符 c;右扩 rk5[3,5]{a,b,c}3ans=3
i=4删除 s [3] 字符 a;无法继续右扩5[4,5]{b,c}2ans=3
i=5删除 s [4] 字符 b;右扩 rk6[5,6]{c,b}2ans=3
i=6删除 s [5] 字符 c;无法继续右扩6[6,6]{b}1ans=3

最终返回 ans = 3

四、关键语法与内置方法、基础类型 & 包装类积累

1. String 内置方法

  1. s.length():获取字符串长度,必须带括号;数组长度写法arr.length(无括号)
  2. s.charAt(index):String 内置方法,根据下标获取对应字符;⚠️方法名全小写charAt,禁止写成CharAt

2. Java 基础类型与对应包装类

核心规则:Java 中Set、List、Map等集合泛型不支持基础数据类型,必须使用包装类。支持自动装箱、自动拆箱,无需手动转换。

基础类型(基本类型)对应包装类刷题场景示例
byteByteSet<Byte>
shortShortMap<Short,String>
intIntegerSet<Integer>(两数之和、最长连续序列高频)
longLongMap<Long,Integer>
floatFloat极少用到
doubleDouble极少用到
booleanBooleanSet<Boolean>
charCharacter本题Set<Character>

3. HashSet 常用方法

  • occ.add():字符加入集合
  • occ.remove():删除指定字符
  • occ.contains():判断字符是否存在集合内

4. 通用工具方法

Math.max(a,b):返回两个数字中较大的值,用于更新最长长度

五、高频易错点汇总

  1. 大小写错误s.CharAt()❌ 正确:s.charAt()
  2. 缺少调用对象:不能单独写charAt(),必须写成s.charAt(下标)
  3. 混淆lengthlength():字符串不要漏写括号
  4. 逻辑误区:不要一次性把全部字符放入集合;集合occ只保存当前窗口内字符
    • 窗口扩张 → add;窗口左移收缩 → remove;保持集合与窗口内容同步
  5. rk 初始值设为-1:窗口初始为空,保证第一轮循环可以访问下标 0 的字符
  6. if(i != 0)判断:i=0 是第一轮,窗口左侧没有移出元素,无需执行 remove

六、变量名称释义(刷题通用简写)

  • occ:occurrence,窗口内已经出现的字符集合
  • rk:right index,滑动窗口右指针
  • i:滑动窗口左指针
  • ans:answer,保存最终答案(最长无重复子串长度)
http://www.jsqmd.com/news/1300141/

相关文章:

  • 2026年07月电动螺栓拉伸器制造企业综合能力与选型框架分析 - 卓企推荐
  • 视频转PPT终极指南:10倍提升工作效率的完整解决方案
  • 本地同城GEO优化服务 助力实体商家提升AI搜索排名曝光高效获客
  • 【AI流量分析实战指南】:从零搭建实时异常检测系统,3天掌握企业级流量洞察能力
  • 抗体分子结构与免疫机制解析
  • 现实实务中编制合并报表的简化技巧
  • 揭秘WAS Node Suite:ComfyUI扩展套件的技术架构与实战应用
  • Verilog位宽操作:拼接与截位的工程实践与调试技巧
  • 3步解锁你的数字记忆宝库:用WeChatMsg让聊天记录真正属于你
  • VC++ MFC系统托盘功能完整实现:从API原理到健壮封装
  • AI辅助学术写作:论文引言生成技术解析
  • 不用折腾!连连控才是普通人最省心的远程工具
  • C++跳转语句详解:break、continue、goto、return实战指南
  • 从供应商准入到费用报销,Alora AI如何实现全场景智能审核?
  • 豆包优化怎么选?5家主流服务商特点与适合人群盘点 - 优企甄选
  • 基于Web的在线考试系统设计与实现:Vue+SpringBoot技术解析
  • Verilog硬件描述语言核心语法与FPGA设计实践指南
  • 动态数码管显示:从硬件驱动到软件扫描的实战指南
  • MOSFET从原理到实战:结构、工作区、驱动与选型全解析
  • InnoDB为什么不用跳表,Redis为什么不用B+树?
  • Simulink整车动力学建模:7DOF与14DOF模型实践指南
  • 聚龙汇刘睿带学员参加杭州跨境电商投资峰会 - 全域品牌推荐
  • 地铁客流预测系统:Python+Django+Vue.js全栈开发实践
  • VirtualLab Fusion材料数据导入指南与最佳实践
  • 3个秘诀快速上手黑苹果:OpenCore完整安装指南让普通PC变身macOS工作站
  • 线下销售如何实现过程留痕?智能工牌品牌及选型指南
  • 2026 年福州叉车租赁、吊车租赁,厂房吊装搬运怎么选不踩坑 - LYL仔仔
  • VMware虚拟机PXE网络启动全流程搭建与排错指南
  • Qoder CLI:开源AI编程助手从安装到实战完整指南
  • 写标书熬了 3 周没思路?我用 LinkMed 深度检索 2 小时出了框架