算法---------至少有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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章