尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

LeetCode 第3题《无重复字符的最长子串》笔记

LeetCode 第3题《无重复字符的最长子串》笔记
📅 发布时间:2026/7/23 5:15:59

一、题目回顾

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

示例:

  • 输入:s = "abcabcbb"

  • 输出:3

  • 解释:因为无重复字符的最长子串是"abc",所以长度为 3。

提示:

  • 0 <= s.length <= 5 * 10^4

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


二、核心知识点

知识点1:滑动窗口的核心思想

滑动窗口是处理子串问题的经典方法,用两个指针(左、右)维护一个动态窗口。

  • 右指针 (right):负责向右扩展,将新字符加入窗口。

  • 左指针 (left):负责在发现重复时,将窗口左侧收缩到重复字符之后。

  • 核心目标:始终保证窗口内所有字符不重复,并记录窗口长度的最大值。

形象理解:想象一个可以伸缩的“窗口”在字符串上滑动,右边界不断尝试扩大,左边界在遇到重复时向右收缩。


知识点2:关键数据结构last_pos数组

作用:快速查询一个字符是否在窗口内,以及它上一次出现的位置。

定义:int last_pos[128];

存储逻辑:

  • 下标:字符的 ASCII 码值(例如'a'的 ASCII 码是 97)。

  • 值:该字符最后一次出现的位置索引。

  • 初始值设为-1,表示该字符从未出现。

为何固定128:足以覆盖所有标准 ASCII 字符,空间开销极小(512字节)。

图解存储结构:

字符: a b c d e ... z ASCII: 97 98 99 100 101 ... 122 last_pos数组: 索引: 0 1 2 ... 97 98 99 100 ... 127 [ ][ ][ ] [3 ][5 ][2 ][-1 ] [ ] 不 不 不 'a' 'b' 'c' 'd' 用 用 用 的 的 的 的 值 值 值 值

知识点3:核心判断逻辑last_pos[ch] >= left

问题:为什么这一句就能判断字符ch是否重复?

解答:它判断的是字符ch上一次出现的位置是否在当前窗口内。

  • last_pos[ch]:字符ch上一次出现的位置。

  • left:当前窗口的左边界。

  • 当前窗口范围是[left, right]。

判断逻辑:

  • 若last_pos[ch] >= left→ 该字符的上次出现位置在窗口内 →重复!

  • 若last_pos[ch] < left→ 该字符的上次出现位置已被移出窗口 →不重复,可以安全加入。

图解三种情况:

情况1:字符在窗口内(重复)

字符串: a b c a b 索引: 0 1 2 3 4 [===窗口===] left=1, right=3 要加入 right=4 的 'b' last_pos['b'] = 1 (在索引1) 判断:1 >= left(1)? 是!✅ → 重复了!

情况2:字符不在窗口内(不重复)

字符串: a b c a b 索引: 0 1 2 3 4 [===窗口===] left=2, right=3 要加入 right=4 的 'b' last_pos['b'] = 1 (在索引1) 判断:1 >= left(2)? 否!❌ → 没重复!

知识点4:窗口滑动操作(处理重复的步骤)

当遇到重复字符ch时,执行以下三步:

  1. 移动左指针:left = last_pos[ch] + 1;(直接跳到重复字符的下一个位置,保证新窗口无重复)。

  2. 更新位置:last_pos[ch] = right;(将ch的最新位置更新为当前位置)。

  3. 更新最大长度:max_len = max(max_len, right - left + 1);

图解执行过程(以s = "abcabcbb"为例):

第4步:right=3, ch='a', last_pos['a']=0, left=0 发现重复!left从0跳到1 窗口从 [a,b,c] 变为 [b,c,a] 第5步:right=4, ch='b', last_pos['b']=1, left=1 发现重复!left从1跳到2 窗口从 [b,c,a] 变为 [c,a,b]

知识点5:为什么你的初步想法需要修正?

你的初步想法:

“从第一个开始,遇到重复就截止,然后从这个重复出现的最后一个开始接着计数。”

问题与修正:

  • 这个想法接近滑动窗口,但移动方式有误。

  • 不应从“重复的最后一个”开始,而应从重复字符第一次出现位置的下一个位置开始,即left = last_pos[ch] + 1。

  • 这样才能保证新窗口内不再包含重复字符。

举例说明:

s = "abca" 正确做法:遇到第二个'a'时,left从0跳到1,窗口变为 [b,c,a] 你的做法:从第二个'a'开始,窗口为 [a],漏掉了 [b,c,a]

三、常见错误总结

错误1:只检查相邻字符

  • 错误写法:if (s[i] == s[i-1])

  • 问题分析:只能发现像"aa"这种紧挨着的重复,无法发现"abca"中相距较远的重复字符'a'。

  • 正确做法:必须用last_pos数组检查所有出现过的字符,判断其是否在当前窗口内。

错误2:左指针移动方式错误

  • 错误写法:left++;(一次只移动一位)

  • 问题分析:窗口内可能仍然存在其他重复字符,效率低且容易出错。例如"abcb"中遇到第二个'b'时,left应跳到2,而不是1。

  • 正确做法:应直接跳跃到重复字符的下一个位置:left = last_pos[ch] + 1;

错误3:获取字符串长度方式错误

  • 错误写法:int len = sizeof(s);

  • 问题分析:当s是函数参数(指针)时,sizeof(s)获取的是指针本身的大小(在64位系统上是8字节),而不是字符串长度。

  • 正确做法:使用int len = strlen(s);(需要包含#include <string.h>)。

错误4:last_pos数组未初始化

  • 错误写法:int last_pos[128];直接使用

  • 问题分析:数组初始值为随机值(内存中的垃圾数据),会导致last_pos[ch]判断错误,程序行为不可预测。

  • 正确做法:必须将所有元素初始化为-1,表示所有字符都未出现。可以用循环或memset(last_pos, -1, sizeof(last_pos));。


四、完整解题模板

int lengthOfLongestSubstring(char* s) { int len = strlen(s); //计算字符串长度 if (len == 0) return 0; int left = 0; int max_len = 0; int last_pos[128]; // 128个位置,对应128个ASCII字符 // 初始化为-1 for (int i = 0; i < 128; i++) { last_pos[i] = -1; } //滑动窗口主程序 for (int right = 0; right < len; right++) { char ch = s[right]; //判断重复并移动左指针 if (last_pos[ch] >= left) { left = last_pos[ch] + 1; } //更新位置和最大长度 last_pos[ch] = right; int cur_len = right - left + 1; if (cur_len > max_len) { max_len = cur_len; } } return max_len; }

代码要点:

  • last_pos数组大小固定为128,适用于所有ASCII字符。

  • 左指针left只向右移动(从不回退),保证了 O(n) 的时间复杂度。

  • 每次循环都更新max_len,确保记录历史最大值。


五、复杂度分析

项目复杂度说明
时间复杂度O(n)其中n是字符串长度。每个字符最多被右指针访问一次,被左指针访问一次(当它被移出窗口时)。所有操作(数组读写、比较)均为 O(1)。
空间复杂度O(1)last_pos数组大小固定为128,与输入字符串长度无关。只使用了常数个额外变量(left,max_len,right等)。

相关新闻

  • LM3S2965定时器与看门狗寄存器深度解析与实战避坑指南
  • 欧米茄保养价格查询|全部地址与售后服务电话权威信息公告(2026年7月最新) - 欧米茄官方服务中心
  • XXL猛汉特区连线错误排查与网络优化指南

最新新闻

  • 流式回答一卡一卡:Token 速率控制与平滑渲染实现
  • 中国爱彼2026年7月最新网点地址与售后热线电话通知 - 爱彼中国官方服务中心
  • C++实战:从零构建网络天气查询工具,贯通面向对象与JSON解析
  • 雅典中国售后服务中心服务电话及24小时详细地址实地考察报告多信源验证(2026年7月更新) - 亨得利官方服务中心
  • 货代集体摆烂,大批卖家的货无路可走?
  • 2026年7月最新积家沈阳市府恒隆广场维修保养服务电话 - 积家官方售后服务中心

日新闻

  • 亨得利盐城维修点在哪里?手表维修保养地址指南**公示(2026年7月最新) - 亨得利官方
  • 提升.NET API安全性:Boxed.AspNetCore.Swagger认证授权最佳实践
  • 帝舵佛山**网点地址更新:2026年7月售后热线电话与服务客户指南 - 帝舵中国官方服务中心

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号