Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times.
Example 1:
Input: s = "aaabb", k = 3 Output: 3 The longest substring is "aaa", as 'a' is repeated 3 times.
Example 2:
Input: s = "ababbc", k = 2 Output: 5 The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
思路:先统计每个出现的个数,然后从字符串开头开始遍历 找出第一个不符合出现次数要求的位置,进行递归遍历从开始到这个位置的子串是否符合要求,遍历完之后lastStart+1 从这个位置之后算作新的开始。
public class Solution {
public int longestSubstring(String s, int k) {
int n=s.length();
if(n<k) return 0;
int []counter=new int[26];
boolean valid[]=new boolean[26];
char []dic=s.toCharArray();
for(int i=0;i<s.length();i++){
counter[s.charAt(i)-'a']++;
}
boolean isValid=true;
for(int i=0;i<26;i++){
if(counter[i]>0&&counter[i]<k){
isValid=false;
valid[i]=false;
}
else valid[i]=true;
}
if(isValid) return s.length();
int max=0;
int lastStart=0;
for(int i=0;i<n;i++){
if(valid[dic[i]-'a']==false){
max=Math.max(max,longestSubstring(s.substring(lastStart,i),k));
lastStart=i+1;
}
}
max=Math.max(max,longestSubstring(s.substring(lastStart,n),k));
return max;
}
}
思路类似 用递归不断缩小范围
public int longestSubstring(String s, int k) {
char[] str = s.toCharArray();
return helper(str,0,s.length(),k);
}
private int helper(char[] str, int start, int end, int k){
if(end<start) return 0;
if(end-start<k) return 0;//substring length shorter than k.
int[] count = new int[26];
for(int i = start;i<end;i++){
int idx = str[i]-'a';
count[idx]++;
}
for(int i = 0;i<26;i++){
if(count[i]==0)continue;//i+'a' does not exist in the string, skip it.
if(count[i]<k){
for(int j = start;j<end;j++){
if(str[j]==i+'a'){
int left = helper(str,start,j,k);
int right = helper(str,j+1,end,k);
return Math.max(left,right);
}
}
}
}
return end-start;
}