問題描述
找到給定字符串(由小寫字符組成)中的最長子串 T , 要求 T 中的每一字符出現次數都不少於 k 。輸出 T 的長度。
示例 1:
輸入:
s = "aaabb", k = 3
輸出:
3
最長子串爲 “aaa” ,其中 ‘a’ 重複了 3 次。
示例 2:
輸入:
s = "ababbc", k = 2
輸出:
5
最長子串爲 “ababb” ,其中 ‘a’ 重複了 2 次, ‘b’ 重複了 3 次。
解決思路
1、將所有的字母數目做一統計
2、有左右兩個指針,如果對應的字母數量小於k,向內移動指針
3、找到左右兩個指針中間數量小於k的字母,從此處分開,遞歸
4、結束條件:當剩餘字符的數量小於k,返回0
代碼實現
package solution;
class Solution {
public static void main(String[] args) {
Solution solution=new Solution();
int i=solution.longestSubstring("ababbc",2);
System.out.println(i);
}
public int longestSubstring(String s, int k) {
return part(s.toCharArray(),k,0,s.length()-1);
}
public int part(char[] arr,int k,int left,int right){
//所剩字母數量小於k,說明不滿足條件
if(right-left+1<k){
return 0;
}
//記錄字符數量的數組
int[] counts=new int[26];
//統計數量
for(int i=left;i<=right;i++){
counts[arr[i]-'a']=counts[arr[i]-'a']+1;
}
//向右移動指針
while (right-left+1>=k&&counts[arr[left]-'a']<k){
left++;
}
//向左移動指針
while (right-left+1>=k&&counts[arr[right]-'a']<k){
right--;
}
if(right-left+1<k){
return 0;
}
for (int i=left;i<=right;i++){
if(counts[arr[i]-'a']<k){
//如果中間還有不滿足條件的字符,遞歸
return Math.max(part(arr,k,left,i-1),part(arr,k,i+1,right));
}
}
return right-left+1;
}
}