Copy Input: s = "aaabb", k = 3
Output: 3
The longest substring is "aaa", as 'a' is repeated 3 times.
Copy Input: s = "ababbc", k = 2
Output: 5
The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.
思路: 由于题目说了string只包含lowercase的字母,所以我们可以列举包含1个字母到包含全部26个字母情况下,找出满足条件的最长子串.其中unique代表不同的字母个数,atLeastK代表在子串中重复出现的次数至少k次的字母的个数
Copy class Solution {
public int longestSubstring ( String s , int k) {
int [] map = new int [ 256 ];
int start = 0 , end = 0 , unique = 0 , atLeastK = 0 ;
int maxLen = 0 ;
for ( int target = 1 ; target <= 26 ; target ++ ) {
Arrays . fill (map , 0 );
start = 0 ;
end = 0 ;
unique = 0 ;
atLeastK = 0 ;
while (end < s . length ()) {
if (map[ s . charAt (end)] == 0 ) {
++ unique;
}
if (map[ s . charAt (end)] == k - 1 ) {
++ atLeastK;
}
++ map[ s . charAt (end)];
++ end;
while (unique > target) {
if (map[ s . charAt (start)] == k) {
-- atLeastK;
}
if (map[ s . charAt (start)] == 1 ) {
-- unique;
}
-- map[ s . charAt (start)];
++ start;
}
// 当子串中不同字母的个数等于target,且所以这些不同的字母至少出现k次,更新maxLen
if (unique == target && atLeastK == unique) {
maxLen = Math . max (maxLen , end - start);
}
}
}
return maxLen;
}
}
Copy class Solution {
public int longestSubstring ( String s , int k) {
return findLongestSubstring(s , k , 0 , s . length() - 1 ) ;
}
public int findLongestSubstring ( String s , int k , int start , int end) {
if (start > end || end - start + 1 < k) {
return 0 ;
}
int [] count = new int [ 26 ];
for ( int i = start; i <= end; i ++ ) {
++ count[ s . charAt (i) - 'a' ];
}
for ( int i = 0 ; i < 26 ; i ++ ) {
if (count[i] > 0 && count[i] < k) {
int index = s . indexOf (( char )(i + 'a' ) , start);
return Math.max(findLongestSubstring(s, k, start, index - 1), findLongestSubstring(s, k, index + 1, end));
}
}
return end - start + 1 ;
}
}
3. Time & Space Complexity