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

无重复字符的最长子串 — AI 写了两版,暴力解被面试官一句话怼回来了

读完本文你将了解:滑动窗口的直觉推导 | AI 从暴力到优化的完整演进 | 面试中的细节加分项


📋 题目

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

项目说明
输入s = “abcabcbb”
输出3
解释最长无重复子串是 “abc”,长度为 3
约束0 ≤ s.length ≤ 5×10⁴,字符集为 ASCII

💡 先问一个问题

如果让 ChatGPT 第一次写这道题,它会怎么写?

我实测了一下。它第一反应居然是——三层循环

deflength_of_longest_substring(s:str)->int:max_len=0foriinrange(len(s)):forjinrange(i,len(s)):sub=s[i:j+1]iflen(set(sub))==len(sub):max_len=max(max_len,len(sub))returnmax_len

不能说错,但面试官看到这段代码,表情是这样的 😑

复杂度:时间 O(n³),空间 O(n)

别笑。这个解法的思路很朴素——枚举所有子串,检查每个子串是否有重复字符。三层循环里,最内层 set(sub) 遍历了子串的每个字符。

人类直觉 ≈ 暴力枚举,这很自然。但面试考的不是"能不能写出来",而是"能不能意识到问题在哪"。


🤖 AI 的自我优化

第 1 次优化:从 O(n³) 到 O(n²)

AI 看到自己的代码后,第一反应是去掉最内层 set 的重复遍历,用滑动窗口的雏形:

deflength_of_longest_substring(s:str)->int:max_len=0foriinrange(len(s)):seen=set()forjinrange(i,len(s)):ifs[j]inseen:breakseen.add(s[j])max_len=max(max_len,j-i+1)returnmax_len

复杂度:时间 O(n²),空间 O(min(n, |Σ|))

改进在哪?用set实时跟踪当前窗口的字符,遇到重复就提前 break,而不是每次都生成整个子串再检查。

但面试官依然不满意——“n 最大 5×10⁴,n² 是 2.5×10⁹,超时。”

第 2 次优化:真正的滑动窗口(O(n))

AI 终于意识到,当右指针发现重复字符时,左指针不用一步步挪,可以直接跳到重复字符的下一个位置。

deflength_of_longest_substring(s:str)->int:char_index={}left=0max_len=0forright,chinenumerate(s):ifchinchar_indexandchar_index[ch]>=left:left=char_index[ch]+1char_index[ch]=right max_len=max(max_len,right-left+1)returnmax_len

复杂度:时间 O(n),空间 O(min(n, |Σ|))

关键变化只有一行:left = char_index[ch] + 1。当字符重复时,左指针直接跳到重复字符的下一个位置,而不是像上一步那样 left++ 一步步挪。

暴力枚举
O(n³)

窗口雏形
O(n²)

滑动窗口
O(n)

哈希表优化
O(n) 空间

☕ Java 实现

publicintlengthOfLongestSubstring(Strings){Map<Character,Integer>charIndex=newHashMap<>();intleft=0,maxLen=0;for(intright=0;right<s.length();right++){charch=s.charAt(right);if(charIndex.containsKey(ch)&&charIndex.get(ch)>=left){left=charIndex.get(ch)+1;}charIndex.put(ch,right);maxLen=Math.max(maxLen,right-left+1);}returnmaxLen;}

HashMap 替代 dict,containsKey替代in,逻辑完全对称。面试中写出 Java 版,面试官知道你是个能写工程的。


🔍 算法模式拆解

这道题是滑动窗口(Sliding Window)模式的经典代表。

什么时候用滑动窗口?

  • 处理连续子数组/子串问题
  • 需要在一个区间内维护某种约束(无重复、和 ≤ K、至少包含某些字符)
  • 右指针拓展窗口,左指针收缩窗口

滑动窗口的通用模板:

defsliding_window(s:str)->int:left=0result=0window={}# 或 set / 计数器forright,chinenumerate(s):# 更新窗口状态update(window,ch)# 不满足条件时收缩左边界whileinvalid(window):remove(window,s[left])left+=1# 更新结果result=max(result,right-left+1)returnresult

模式变体:

  • 固定窗口大小:滑动窗口的平均值(LeetCode 643)
  • 可变窗口:无重复字符的最长子串(本题)
  • 双指针并行:最小覆盖子串(LeetCode 76)

无重复

和≤K

字符覆盖

输入数组/字符串

需要连续子区间?

窗口大小固定?

其他模式

固定滑动窗口
O(n)

可变滑动窗口
O(n)

需要额外约束?

哈希表+左右指针

前缀和+双指针

计数器+双指针


🏗️ 真实产品场景

Slack 的消息会话窗口中,用户可能会在短时间内刷出大量消息。系统需要检测当前视图中的消息序列里,不重复的标签/用户提及是否连续——这直接决定了是否需要提示"你可能错过了 @someone 的回复"。

另一个场景:Twitter 的时间线滑动。用户在滑动时,客户端需要确保 feed 中连续 N 条推文没有重复内容(广告除外)。用滑动窗口算法,客户端可以在 O(n) 时间内扫描整个时间线,标记出需要过滤的重复项。


✅ 面试官的点评

写到什么程度算"通过":

  • 写出 O(n) 的滑动窗口解法 → 通过
  • 能解释为什么 O(n²) 版本会超时 → 加分
  • 能处理字符集扩展(Unicode/ASCII)→ 加分

常见踩坑点:

  • 忘记char_index[ch] >= left判断——当左指针已经越过某个字符的旧位置时,旧索引不应该再影响窗口收缩
  • 更新max_len的时机:要在每次右指针移动后更新,而不是只在收缩后更新
  • 边界条件:空字符串返回 0

加分细节:

  • 讨论字符集规模对空间复杂度的影响(ASCII 128 vs Unicode 1M+)
  • 如果输入是字节流(streaming),滑动窗口也可以在线处理

📊 同类题推荐

题目难度一句话思路
LeetCode 76最小覆盖子串Hard两个哈希表+滑动窗口,找到包含所有目标字符的最短窗口
LeetCode 424替换后的最长重复字符Medium滑动窗口+频率统计,窗口内最多可替换 K 个字符
LeetCode 904水果成篮Medium滑动窗口+最多两种水果的约束,本质是"最多两个不同字符的最长子串"

来源说明

  • ✅ 已验证:LeetCode 官方题解 + AI 实测
  • 📄 来源:算法导论(CLRS)第 15 章——动态规划与滑动窗口
http://www.jsqmd.com/news/1154914/

相关文章:

  • 构建弹性网络之分布式负载均衡技术(一):特点与功能
  • 2026年西安第一次装修靠谱家装公司推荐|首次装修本地人实测避坑榜 - 子柔传媒
  • TLP241A光耦与PIC18F46K22在工业隔离信号传输中的优化设计
  • PIC18F8722与CMT-8540S-SMT蜂鸣器声音控制实战
  • Magpie窗口缩放工具:Windows屏幕放大的终极解决方案
  • 长沙除甲醛公司全维度评估:绿舒环保等6家口碑横评建议 - 绿舒环保母婴除甲醛
  • TLP241A光隔离继电器与PIC18F4458在工业控制中的应用
  • TPA3138D2与PIC18F46K20音频系统设计与优化
  • 5分钟快速修复洛雪音乐六音音源失效问题:完整解决方案指南
  • 基于ADS127L11和STM32的高精度模拟信号采集方案
  • 机器人二次开发机器狗巡检?环境适应性强
  • 中国关系型数据库头部厂商最新份额:腾讯云三项增速第一
  • 3步快速修复:DistroAV插件NDI Runtime缺失终极指南
  • 广东省考备考机构怎么选?2026超全实测复盘与避坑指南前言
  • 第21届全国大学生智能汽车竞赛 人工智能视觉组游戏系统比赛版及计分规则介绍
  • 2026服装店收银系统开发公司测评:覆盖技术、服务的全方位优质服务商解析 - U渠道
  • 2026年国内机械手吸盘主流供应厂家名录盘点 - 热点速览
  • 锂离子电池主动均衡方案:基于MCP3202与PIC18F96J65的设计
  • 计算机毕业设计之基于SSM的影评系统的设计与实现
  • PyTorch Embedding层实战:从One-Hot到10维向量,3步构建电影推荐模型
  • 【ROS2】 命令行工具速查手册:从入门到日常调试必备
  • scrcpy安卓投屏实战指南:高效控制Android设备的完整方案
  • 如何突破网盘限速:开源直链下载助手的终极指南
  • ADS122U04与MKV42F256VLH16构建高精度数据采集系统
  • 高精度数据采集方案:ADS1262与PIC18F65K40的SPI接口优化
  • 无锡本地劳力士回收老店逸程,实体交易出手腕表更安心 - 全城热点
  • 电气隔离技术:TLP241A光继电器与PIC18F87J11应用方案
  • 北京金银变现避坑指南,7 家中检认证回收门店一览,实时金价透明称重核验 - 分享测评官
  • MatAnyone:免费AI视频抠像神器,3分钟实现专业级背景替换
  • PIC18微控制器实现锂电池电压监测与平衡系统设计