滑动窗口法通过left和right指针维护无重复字符的子串,用哈希表记录字符最后出现位置,left取max(left, last_occurrence[char] + 1)确保不回退,每次right移动后更新最大长度。

滑动窗口是解决“无重复字符的最长子串”这类问题最直观、高效的方法,核心在于用两个指针维护一个窗口,保证窗口内字符不重复,并动态调整窗口大小来寻找最长合法子串。
窗口如何定义和移动
用 left 和 right 两个指针表示窗口左右边界(闭区间),初始都指向字符串开头。right 向右扩展,每加入一个新字符 s[right],检查它是否已在当前窗口中出现过。若已存在,就将 left 不断右移,直到窗口内不再包含该重复字符——这一步靠哈希表记录每个字符最近出现的位置,或用集合+逐个删除实现。
- 推荐用 哈希表(如 Python 的 dict)记录字符最后一次出现的索引,这样 left 可直接跳到 max(left, last_occurrence[char] + 1),避免逐个试探
- 每次 right 移动后,更新当前窗口长度 right − left + 1,并维护最大值
- 注意:left 不能往回退,所以要取 max,确保窗口始终合法且左边界单调不减
关键细节:何时更新 left
不是只要遇到重复就立刻移动 left,而是当 s[right] 在窗口内已存在时,才需收缩。判断依据是:s[right] 上次出现的位置 ≥ left。如果上次位置在窗口外(即
- 例如 s = "abba",当 right=3(第二个 'a'),last['a']=0,而此时 left=2,0
- 但当 right=2(第二个 'b'),last['b']=1 ≥ left=0,于是 left = max(0, 1+1) = 2
代码结构与变量管理
需要三个核心变量:left(窗口左界)、max_len(结果)、char_index(记录字符最新下标)。遍历 right 从 0 到 len(s)-1,对每个 s[right]:
- 若 s[right] 已在 char_index 中且其位置 ≥ left,则更新 left
- 更新 char_index[s[right]] = right
- 计算当前长度 right − left + 1,更新 max_len
时间与空间复杂度
每个字符最多被访问两次(right 进一次,left 出一次),因此时间复杂度为 O(n);哈希表最多存全部不同字符,空间复杂度为 O(min(m,n)),其中 m 是字符集大小(如 ASCII 是常数 128)。


















