【LeetCode】395. 至少有 K 个重复字符的最长子串
作者:互联网
题目链接:https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/
本题使用分治思想解决
(也可以使用滑动窗口的思想解决,但是我不会)
首先对于整个字符串,如果某个子串包含了【在字符串中出现次数少于k】的字符,那么根据题目定义,这个子串就不符合要求,因此,可以根据这些字符的位置,将整个字符串分割为多个子字符串,在这些子字符串中递归搜索符合要求的其子串,然后,在这些符合要求的子串中获取最大的一个,得出答案即可。
代码(Java)
class Solution {
/*
* L: 当前要处理的字符串的左端
* R: 当前要处理的字符串的右端
*/
public int sovle (String s, int k, int L, int R) {
// 当L>R时,无法形成字符串,直接返回0
if (L > R) return 0 ;
// freq 频率数组,用于记录当前字符串每个字符出现的频率
int[] freq = new int[26] ;
for (int i = L;i <= R;i++) {
freq[s.charAt(i) - 'a'] ++ ;
}
// 根据出现次数少于k的字符分割成多个子字符串
int start = L ;
int ans = 0 ;
for (int i = L;i <= R;i++) {
if (freq[s.charAt(i) - 'a'] < k && freq[s.charAt(i) - 'a'] != 0) {
ans = Math.max(ans, sovle(s, k, start, i - 1)) ;
start = i + 1 ;
}
}
// 如果start等于L,那么说明当前的字符串中,每个字符出现次数都不小于k
// 那么直接返回当前字符串长度即可
if (start == L) return R - L + 1 ;
// 如果start 不等于R + 1,说明最后一个字符出现次数不小于k
// 在循环中,就会把最后一段漏掉
// 所以这里需要特殊处理
if (start != R + 1) {
ans = Math.max(ans, sovle(s, k, start, R)) ;
}
return ans ;
}
public int longestSubstring(String s, int k) {
int n = s.length() ;
if (n == 0) return 0 ;
return sovle(s, k, 0, s.length() - 1) ;
}
}
标签:子串,字符,int,符合要求,395,字符串,freq,LeetCode 来源: https://www.cnblogs.com/Suans/p/14455747.html