无重复字符的最长子串:遇到重复就把左指针跳过去
定长窗口几页中窗口宽度都固定为 k。这一流派里窗口宽度不固定——由一个条件来撑大或收紧,形如一只毛毛虫 (caterpillar):右指针 R 一路向前纳入新字符把窗口撑长;一旦窗内出现重复字符,就把左指针 L
跳到那个重复字符的右边,把窗口缩回「无重复」状态。整个过程 L、R 都只增不减,各扫一遍 →
。每个 R 处的合法窗口长度
取最大,就是答案。
1 · 为什么 L 可以「直接跳」,不用一格格退
遇到重复字符 c 时,窗口里那个旧的 c 在下标 last[c]。只要它还在窗里,窗口就不满足「无重复」约束——所以左边界至少要推到 last[c]+1,把旧 c 移出窗口。比
last[c]+1 更靠右没必要(会丢掉本可保留的字符),更靠左又没消除重复。于是 L 一步到位跳过去,绝不回退——这正是它
而非
的关键。
同一副「右扩 + 左缩」的骨架,改一下收缩条件与记录目标就能解一大类题:这里是「窗内无重复 → 求最长」;长度最小的子数组则换成「窗内和 ≥ target → 求最短」。一个求最长、一个求最短,正好覆盖变长窗口的两种典型形态。