滑动窗口中记录字符最后出现位置

相关概念:Algorithm

求“无重复字符的最长子串”时,一个很实用的思路不是反复移动左右指针去删字符,而是:

用一张索引表,直接记录每个字符最近一次出现的位置。

核心写法

public int lengthOfLongestSubstring(String s) {
  int[] index = new int[128];
  int ans = 0;
  for (int i = 0, j = 0; i < s.length(); i++) {
    j = Math.max(index[s.charAt(i)], j);
    ans = Math.max(i - j + 1, ans);
    index[s.charAt(i)] = i + 1;
  }
  return ans;
}

这个写法为什么顺

关键点只有两个:

  • index[c] 记录字符 c 上次出现的“次序”,也就是索引 +1
  • j 始终表示当前无重复窗口的最小合法起点

这样一来,当某个字符重复出现时,窗口左边界不需要一步步挪,而是可以直接跳到正确位置。

为什么存 i + 1

因为数组默认值是 0

把“未出现过”自然编码成 0,就能和真正的索引位置区分开。

这个思路的价值

它本质上不是某道题的模板,而是一类常见技巧:

当既关心“最近一次出现的位置”,又希望窗口能快速跳跃时,用索引表往往比显式维护集合更利落。