題目
找到給定字符串(由小寫字符組成)中的最長子串 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;
}
}