算法---------至少有K个重复字符的最长子串(Java版本)

题目

找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。

示例 1:

输入:
s = "aaabb", k = 3

输出:
3

最长子串为 "aaa" ,其中 'a' 重复了 3 次。
示例 2:

输入:
s = "ababbc", k = 2

输出:
5

最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。

解决方法

解题思路:

递归拆分子串,分治。
先统计出每个字符出现的频次,维护一对双指针,从首尾开始统计,从首尾往中间排除,如果出现次数小于k则不可能出现在最终子串中,排除并挪动指针,然后得到临时子串,依次从头遍历,一旦发现出现频次小于k的字符,以该字符为分割线,分别递归求其最大值返回。

class Solution {
    public int longestSubstring(String s, int k) {
        char[] chars = s.toCharArray();
        return count(chars,0,chars.length-1,k);        
    }
    public int count(char[]chars,int start,int end,int minLength){
        if (end - start  +1 < minLength) {
            return 0;
        }
        HashMap<Character,Integer> hashMap = new HashMap<>();
        for (int i = start; i <= end; i++) {
            hashMap.put(chars[i],hashMap.getOrDefault(chars[i],0) + 1);
        }
        while (end -start + 1 > minLength && hashMap.get(chars[start]) < minLength) start++;
        while (end -start + 1 > minLength && hashMap.get(chars[end]) < minLength) end--;
        if (end - start  +1 < minLength) {
            return 0;
        }
        for (int i = start; i <= end; i++) {
            //如果有没有满足的 那么分治
            if (hashMap.get(chars[i]) < minLength) {
                return Math.max(count(chars,start,i-1,minLength),count(chars,i+1,end,minLength));
            }
        }
        return end - start + 1;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章