https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/

    • 题目说了只有小写字母,那么就利用题目本身的限制,

    • 每次尝试的时候把它含有的字符种类限制死

    截图_20210025100031.png

    利用窗口

    • R往右动的情况

      • 1)种类不足
      • 2) 每种字符没有凑齐 K个
    • 如果R一直往右直到越界都没形成一个窗口,说明无答案

    • R什么时候停? 种类超了

    过个例子
    截图_20210425100421.png
    R停,看达标不, 达标, 收集一个答案, 然后左边缩一个
    截图_20210425100452.png
    R扩不动,不达标,不收集答案
    截图_20210525100505.png
    截图_20210525100521.png
    截图_20210525100540.png

    截图_20210625100624.png
    ..
    总而言之,只有种类够,次数也够才收集答案

    没有用滑动窗口加速的解法

    1. public int longestSubstring1(String s, int k) {
    2. char[] str = s.toCharArray();
    3. int N = str.length;
    4. int max = 0;
    5. for (int i = 0; i < N; i++) {
    6. int[] count = new int[256];
    7. int collect = 0;
    8. int satisfy = 0;
    9. for (int j = i; j < N; j++) {
    10. if (count[str[j]] == 0) {
    11. collect++;
    12. }
    13. if (count[str[j]] == k - 1) {
    14. satisfy++;
    15. }
    16. count[str[j]]++;
    17. if (collect == satisfy) {
    18. max = Math.max(max, j - i + 1);
    19. }
    20. }
    21. }
    22. return max;
    23. }

    优化之后

    1. //滑动窗口优化加速
    2. public int longestSubstring2(String s, int k) {
    3. char[] str = s.toCharArray();
    4. int N = str.length;
    5. int max = 0;
    6. for (int require = 1; require < 26; require++) { //字母种类
    7. int[] count = new int[26];
    8. int collect = 0; //目前窗口内收集了几种字符了
    9. int satisfy = 0; //目前窗口内出现次数>=k次的字符,满足了几种
    10. int R = -1; // 窗口右边界
    11. for (int L = 0; L < N; L++) { // L要尝试每一个窗口的最左位置
    12. // [L..R] R+1
    13. while (R + 1 < N && !(collect == require && count[str[R + 1] - 'a'] == 0)) {
    14. R++;
    15. if (count[str[R] - 'a'] == 0) {
    16. collect++;
    17. }
    18. if (count[str[R] - 'a'] == k - 1) {
    19. satisfy++;
    20. }
    21. count[str[R] - 'a']++;
    22. }
    23. // R扩不动了, 看达标不
    24. if (satisfy == require) {
    25. max = Math.max(max, R - L + 1);
    26. }
    27. if (count[str[L] - 'a'] == 1) {
    28. collect--;
    29. }
    30. if (count[str[L] - 'a'] == k) {
    31. satisfy--;
    32. }
    33. count[str[L] - 'a']--;
    34. }
    35. }
    36. return max;
    37. }