给定一个字符串 s ,找出 至多 包含 k 个不同字符的最长子串 T。

示例 1: 输入: s =”eceba”, k =2 输出:3 解释: 则 T 为 “ece”,所以长度为 3。

示例 2: 输入: s =”aa”, k =1 输出:2 解释: 则 T 为 “aa”,所以长度为 2。

滑动窗口 + 记账表

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

记录此时窗口的长度:为7
然后窗口开始缩一个,然后看能不能往下扩。。。,不能往下扩且长度没我现在的7好,舍弃,删记录
image.png
image.png
image.png
..此刻又能往下扩了
image.png
。。。
。。

思考: 为什么想到用窗口? 窗口变大,字符的种类只有不变或变多, 具有单调性

  1. public static int lengthOfLongestSubstringKDistinct(String s, int k) {
  2. if (s == null || s.length() == 0 || k < 1) {
  3. return 0;
  4. }
  5. char[] str = s.toCharArray();
  6. int N = str.length;
  7. int[] count = new int[256];
  8. int diff = 0; //种类
  9. int R = 0; // 有边界
  10. int ans = 0;
  11. for (int i = 0; i < N; i++) {
  12. while (R < N && (diff < k || count[str[R]] > 0)) {
  13. diff += count[str[R]] == 0 ? 1 : 0;
  14. count[str[R++]]++;
  15. }
  16. // R 来到违规的第一个位置(扩不动了)
  17. ans = Math.max(ans, R - i);
  18. diff -= count[str[i]] == 1 ? 1 : 0;
  19. count[str[i]]--;
  20. }
  21. return ans;
  22. }