题目描述
找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。
示例:
输入:
s = "aaabb", k = 3
输出:
3
最长子串为 "aaa" ,其中 'a' 重复了 3 次。
题目链接: https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/
思路
使用两个指针 left, right 表示在 [left, right] 范围内进行判断。首先统计 [left, right] 范围内字母的出现次数存入数组 cnt 中,然后根据字母出现的次数是否大于等于 k,从两边缩小范围。缩小范围后,判断新范围内是否有字符出现的次数小于 k,如果有,说明该字符不可能出现在结果当中,假设该字符的下标为 mid,则递归统计 [left, mid-1] 和 [mid+1, right] 范围内符合条件的长度,取较大者;否则,说明 [left, right] 范围内的字符出现次数均大于等于 k,返回范围的长度 right-left+1.
代码如下:
class Solution {
public:
int longestSubstring(string s, int k) {
if(s.empty() || s.size()<k) return 0;
return count(s, k, 0, s.size()-1);
}
int count(string s, int k, int left, int right){
if(right-left+1<k) return 0;
vector<int> cnt(26, 0);
for(int i=left; i<=right; i++) cnt[s[i]-'a']++;
while(right-left+1>=k && cnt[s[left]-'a']<k) left++;
while(right-left+1>=k && cnt[s[right]-'a']<k) right--;
if(right-left+1<k) return 0;
for(int mid = left; mid<=right; mid++){
if(cnt[s[mid]-'a']<k){
return max(count(s, k, left, mid-1), count(s, k, mid+1, right));
}
}
return right-left+1;
}
};
参考
https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/