Longest Substring with At Least K Repeating Characters
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.
class Solution {
public int longestSubstring(String s, int k) {
if (s == null || s.length() == 0) {
return 0;
}
int max = 0;
// By providing the required distinct alphabets, we create a condition to reduce
// our sliding window
for (int numTargetDistinct = 1; numTargetDistinct <= 26; numTargetDistinct++) {
// finding logest substring with exactly "numTargetDistinct" unique characters
// where each character appears atleast K times
int len = longestDistinct(s, k, numTargetDistinct);
max = Math.max(max, len);
}
return max;
}
private int longestDistinct(String s, int K, int numTargetDistinct) {
Map<Character, Integer> map = new HashMap<>();
int start = 0, end = 0;
int uniqueNum = 0;
int numbersAboveK = 0;
int max = 0;
while (end < s.length()) {
char cEnd = s.charAt(end);
map.put(cEnd, map.getOrDefault(cEnd, 0) + 1);
if (map.get(cEnd) == 1)
uniqueNum++;
if (map.get(cEnd) == K)
numbersAboveK++;
while (uniqueNum > numTargetDistinct) {
char cStart = s.charAt(start);
if (map.get(cStart) == K)
numbersAboveK--;
if (map.get(cStart) == 1)
uniqueNum--;
map.put(cStart, map.get(cStart) - 1);
start++;
}
// If all the unique numbers are occuring atleast K times
if (uniqueNum == numbersAboveK)
max = Math.max(max, end - start + 1);
end++;
}
return max;
}
}