Find the length of the longest substringTof a given string (consists of lowercase letters only) such that every character inTappears no less thanktimes.
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.
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;
}
}
(2) Divide and Conquer
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;
}
}