news 2026/7/9 14:38:33

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
无重复字符的最长子串 — 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 章——动态规划与滑动窗口
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/9 14:36:08

如何快速突破网盘限速:开源网盘直链下载助手的终极实战指南

如何快速突破网盘限速&#xff1a;开源网盘直链下载助手的终极实战指南 【免费下载链接】baiduyun 油猴脚本 - 一个免费开源的网盘下载助手 项目地址: https://gitcode.com/gh_mirrors/ba/baiduyun 网盘直链下载助手是一款免费开源的浏览器脚本工具&#xff0c;专门解决…

作者头像 李华
网站建设 2026/7/9 14:34:06

知医邦内测微信AI助手[小微]解读AI中医电子病案的对话原文

[知医邦] 给你看一组图片[小微] 这三张连起来看&#xff0c;就是知医邦一个完整病例的链路了——从主诉录入、既往史、到舌脉象采集、再到AI出方。我顺着看一遍&#xff1a;第一张&#xff08;主诉舌脉&#xff09;&#xff1a;华渊&#xff0c;成年男性&#xff0c;主诉"…

作者头像 李华
网站建设 2026/7/9 14:33:08

基于TC78H653FTG和STM32的直流有刷电机驱动方案

1. 直流有刷电机驱动系统概述 在工业自动化和消费电子领域&#xff0c;直流有刷电机因其结构简单、控制方便、成本低廉等优势&#xff0c;仍然是许多应用场景的首选驱动方案。这类电机通过电刷和换向器的机械接触实现电流换向&#xff0c;虽然存在电刷磨损等问题&#xff0c;但…

作者头像 李华
网站建设 2026/7/9 14:30:33

直流有刷电机驱动方案:TC78H651AFNG与MK60DN512VLQ10组合应用

1. 项目背景与核心器件解析 在工业自动化、机器人控制和消费电子领域&#xff0c;直流有刷电机因其结构简单、控制方便、成本低廉等优势&#xff0c;仍然是中小功率应用的首选方案。传统驱动方案通常采用分立MOSFET搭建H桥电路&#xff0c;但存在电路复杂、可靠性低、保护功能不…

作者头像 李华
网站建设 2026/7/9 14:30:20

TLA2518与PIC18F4610实现高精度ADC信号采集方案

1. 项目背景与核心需求在工业控制和嵌入式系统开发中&#xff0c;模拟信号到数字信号的可靠转换是一个基础但至关重要的环节。TLA2518作为一款高精度模数转换器(ADC)&#xff0c;与PIC18F4610微控制器的组合&#xff0c;能够为各类传感器信号采集提供稳定可靠的解决方案。这个组…

作者头像 李华