# LeetCode 395. 至少有K个重复字符的最长子串( 前缀和+分治 、枚举+滑动窗口)

class Solution {
public:
vector<int> pre[26];
int len, k;
string s;
int longestSubstring(string s, int k) {
len = s.size();
this->k = k;
this->s = s;
for(int i=0;i<26;i++) pre[i] = vector<int>(len,0);
for(int i=0;i<len;i++){
pre[s[i]-'a'][i] = 1;
}
for(int i=0;i<26;i++){
for(int j=1;j<len;j++){
pre[i][j] += pre[i][j-1];
}
}
return dfs(0,len-1);
}

int dfs(int l,int r){
if(l>r) return 0;
int res = 0;
int minCount = 1e9;
char c;
for(int i=0;i<26;i++){
int cnt = l==0?pre[i][r]:pre[i][r] - pre[i][l-1];
if(cnt < minCount && cnt != 0){
minCount = cnt;
c = i + 'a';
}
}

if(minCount >= k) return r-l+1;

for(int i=l;i<=r;i++){
if(s[i] == c){
continue;
}else{
int j = i;
while(j<=r && s[j] != c){
j++;
}
res = max(res,dfs(i,j-1));
i = j;
}
}
return res;
}
};


class Solution {
public:
int longestSubstring(string s, int k) {
int cnt[26] = {0};
int n = s.size();
int ans = 0;
for(int t = 1;t <= 26;t++){
memset(cnt,0,sizeof cnt);
int l = 0 ,r = 0;
int tot = 0;
while(r<n){
if(cnt[s[r]-'a']++ == 0){
tot++;
}
r++;
while(tot > t){
if(--cnt[s[l]-'a'] == 0){
tot--;
}
l++;
}
bool f = true;
for(int i=0;i<26;i++){
if(cnt[i]>0 && cnt[i] < k) f = false;
}
if(f) ans = max(ans,r-l);
}
}
return ans;
}
};


class Solution {
public:
int longestSubstring(string s, int k) {
int cnt[26] = {0};
int n = s.size();
int ans = 0;
for(int t = 1;t <= 26;t++){
memset(cnt,0,sizeof cnt);
int l = 0 ,r = 0;
int tot = 0, less = 0;

while(r<n){
if(cnt[s[r]-'a']++ == 0){
tot++;
less++;
}
if(cnt[s[r]-'a'] == k){
less--;
}

r++;
while(tot > t){
cnt[s[l] - 'a']--;
if (cnt[s[l] - 'a'] == k - 1) {
less++;
}
if (cnt[s[l] - 'a'] == 0) {
tot--;
less--;
}
l++;
}
if(less == 0) ans = max(ans,r-l);
}
}
return ans;
}
};


01-18 474
02-03 92
04-26 314