给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。
示例 1:
输入:s = “aaabb”, k = 3
输出:3
解释:最长子串为 “aaa” ,其中 ‘a’ 重复了 3 次。
示例 2:
输入:s = “ababbc”, k = 2
输出:5
解释:最长子串为 “ababb” ,其中 ‘a’ 重复了 2 次, ‘b’ 重复了 3 次。
可以进行分治,从大开始一步一步的缩小范围来得到最大的满足条件的最长子串。因为有些字符不满足总数大于k的要求,那么只要是包含该字符的子字符串肯定不行,因此可以按照这样的字符为界限进行分割,然后再进行满足的情况下的进一步判断。
public int longestSubstring(String s, int k) {
return DFS(0, s.length() - 1, k, s);
}
public int DFS(int left, int right, int k, String s) {
int[] cnt = new int[26];
for (int i = left; i <= right; i++) {
cnt[s.charAt(i) - 'a']++;
}
char split = 0;
for (int i = 0; i < 26; i++) {
if (cnt[i] > 0 && cnt[i] < k) {
split = (char) (i + 'a');
break;
}
}
//进行每次DFS的结果得出
if (split == 0) return right - left + 1;
int i = left;
int ans = 0;
//这里其实就是一个分割的过程
//每次找到其实不是split的位置 和结尾是split的位置
while (i <= right) {
while (i <= right && s.charAt(i) == split) i++;
if (i > right) break;
int start = i;
while (i <= right && s.charAt(i) != split) i++;
int len = DFS(start, i - 1, k, s);
ans = Math.max(ans, len);
}
return ans;
}