题目是力扣P395至少有K个重复字符的最长子串
类似于这样字符串求特定规则下的子串的长度的题目一般都可以用滑动窗口解决,但是这个题我没想到怎么滑,换一种思路,对于一段字符串[left,right],我们要判断他是否满足条件,就是判断这一段字符串内的每一个字符,出现的次数是否都大于等于K即可,因此可以想到用map存储每个字符出现的次数,当再一次遍历的时候,发现此时遍历的字符出现的次数比K小,那么我们记录此时的位置,举个例子,我们先记录left-1,当出现某个字符不满足条件的时候,记录此时的位置j,假设只有一个字符不满足要求,那么我们就讲[left,right]分成了[left,j-1]和[j+1,right],这就是为什么我们需要记录left-1和right+1的原因,,当某一段字符串的字符全部满足的时候,我们返回他的长度right-left+1即可,最后求所有子字符串的最大长度即可。
int dfs(string &s,int left,int right,int k){
if(left>right||right-left+1<k) return 0;
unordered_map<int,int>m;
vector<int>pos;
pos.push_back(left-1);
for(int i=left;i<=right;i++){
m[s[i]-'a']++;
}
for(int i=left;i<=right;i++){
if(m[s[i]-'a']>0&&m[s[i]-'a']<k) pos.push_back(i);
}
pos.push_back(right+1);
int n2=pos.size();
if(n2==2) return right-left+1;
int res=0;
for(int i=0;i<n2-1;i++){
res=max(res,dfs(s,pos[i]+1,pos[i+1]-1,k));
}
return res;
}
int longestSubstring(string s, int k) {
int n=s.size();
if(k==1) return n;
if(k>n) return 0;
return dfs(s,0,n-1,k);
}