
题解
本题使用分治策略,如果某个字符的出现次数小于k,则用它将数组分开,再把每个子数组组委参数递归执行.如果都大于k,则将该字符串的长度返回.
 用一个字符分割,往深了分割各子字符串,这个字符分割完成,使用另一个字符进行分割,而不是一次用多个字符进行分割.这个题递归有些绕
代码
 //301-295- 至少有 K 个重复字符的最长子串-0105
    int longestSubstringRes=0;
    public int longestSubstring(String s, int k) {
        if (s.length()<k){
            return 0;
        }
        // 统计个数
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            map.put(c,map.getOrDefault(c,0)+1);
        }
        // 分割
        for (Map.Entry<Character, Integer> entry : map.entrySet()) {
            if (entry.getValue()<k){
                for (String s1 : s.split(entry.getKey().toString())) {
                    // 对分割完成的子串进行递归
                    longestSubstringRes=Math.max(longestSubstringRes,longestSubstring(s1,k));
                }
                return longestSubstringRes;
            }
        }
        return s.length();
    }
 
法二 滑动窗口法
https://leetcode.cn/problems/longest-substring-with-at-least-k-repeating-characters/solution/xiang-jie-mei-ju-shuang-zhi-zhen-jie-fa-50ri1/
 当窗口内满足条件的种类=窗口内字符的种类, 得到一个结果
 窗口内的字符种类一定的情况下,求满足条件的子串
未到达p类–>判断–>达到p类–>判断–>p+1类–>left右移达到p类–>
 当为p+1类时执行同样的步骤
滑动窗口逻辑上优点难度,看代码与注释
// 滑动窗口
public int longestSubstring(String s, int k) {
        int cnt[]=new int[26]; // 统计各字符个数
        int res=0;
        for (int p = 1; p <=26 ; p++) { // p代表窗口内字符的种类
             Arrays.fill(cnt, 0);
            int left=0,right=0,totalKind=0,matchKind=0;// totalKind 总种类  matchKind: 符合条件的种类
            while (right<s.length()){
                char c = s.charAt(right);
                int index=c-'a';
                cnt[index]++;
                if (cnt[index]==1){// 新加入一类
                    totalKind++;
                }
                if (cnt[index]==k){//如果满足条件
                    matchKind++;
                }
                // 如果总种类大于p,左指针右移,减小种类
                while (totalKind>p){
                    char c1 = s.charAt(left++);// 右移
                    int index1 = c1 - 'a';
                    cnt[index1]--;
                    if (cnt[index1]==0){// 去除该元素后少了一类
                        totalKind--;
                    }
                    if (cnt[index1]==k-1){// 满足条件的少了一类
                        matchKind--;
                    }
                }
                // 判断 当为p类时进行判断
                if (totalKind==matchKind){
                    res=Math.max(res,right-left+1);
                }
                 right++;
            }
        }
        return res;
    }
                

















