← 滑动窗口 · Sliding Window / 无重复字符的最长子串:遇到重复就把左指针跳过去 待审核 5 / 7
Longest · 右扩左缩求最长

无重复字符的最长子串:遇到重复就把左指针跳过去

定长窗口几页中窗口宽度都固定为 k。这一流派里窗口宽度不固定——由一个条件来撑大或收紧,形如一只毛毛虫 (caterpillar):右指针 R 一路向前纳入新字符把窗口撑长;一旦窗内出现重复字符,就把左指针 L 跳到那个重复字符的右边,把窗口缩回「无重复」状态。整个过程 LR只增不减,各扫一遍 → O(n)O(n)。每个 R 处的合法窗口长度 RL+1R-L+1 取最大,就是答案。

1 · 为什么 L 可以「直接跳」,不用一格格退

遇到重复字符 c 时,窗口里那个旧的 c 在下标 last[c]。只要它还在窗里,窗口就不满足「无重复」约束——所以左边界至少要推到 last[c]+1,把旧 c 移出窗口。比 last[c]+1 更靠右没必要(会丢掉本可保留的字符),更靠左又没消除重复。于是 L 一步到位跳过去,绝不回退——这正是它 O(n)O(n) 而非 O(n2)O(n^2) 的关键。

同一副「右扩 + 左缩」的骨架,改一下收缩条件记录目标就能解一大类题:这里是「窗内无重复 → 求最长」;长度最小的子数组则换成「窗内和 ≥ target → 求最短」。一个求最长、一个求最短,正好覆盖变长窗口的两种典型形态。