直接回答:滑动窗口。维护窗口 [left, right] 保证内无重复字符,用哈希表记录每个字符最近一次出现的位置。右指针每前进一格读入字符 c:若 c 上次出现位置不小于 left,说明重复在窗口内,把 left 推到该位置 +1;更新 c 的位置,并用窗口长度刷新最大值。每个字符最多进出窗口一次,时间 O(n)、空间 O(字符集)。
展开解析:这是滑动窗口的模板题,核心不变量是「窗口内始终合法」,右指针负责扩张、左指针负责恢复合法性。用「字符→最近下标」的映射比用集合逐个删除更高效:left 直接跳跃式收缩而非一步步挪动。注意 left 只能右移(取 max),不能回退到之前的位置,这是最常见的 bug。变体与追问:字符集已知很小(如纯 ASCII)时可用定长数组代替哈希表;「至多 K 个不同字符的最长子串」「最小覆盖子串」都是同一框架;面试官可能继续问滑动窗口与动态规划解「子串/子数组」问题的边界——窗口适合单调性合法性,DP 适合最优子结构。
示例:
def length_of_longest(s: str) -> int:
last = {}
left = best = 0
for right, ch in enumerate(s):
if ch in last and last[ch] >= left:
left = last[ch] + 1
last[ch] = right
best = max(best, right - left + 1)
return best