问题:给定字符串string,求解至少有k种字符的子串数目有多少?
解法:前指针j,后指针i,遍历指针i;
当子串的字符种类计数达到k时,可以得到包含该子串的所有子串数(len-i,包括它自身);
递增指针j
若当前子串的字符种类计数仍为k,说明当前子串也是符合题意的,求出包含该子串的所有子串数(不包括j前面已有字符,否则会跟前面所求的子串重复)
否则停止递增j,重新遍历i知道子串字符种类的计数重新到达k时。
注意点:由于length(string)<=1000000,所以结果可能导致int溢出(1000000*1000001/2>20亿多),所以本文采用long long 存储
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1000000+5;
char str[MAXN];
int cnt[26];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int k,cnt_k,len;
long long res;
scanf("%s%d",str,&k);
memset(cnt,0,sizeof(cnt));
len=strlen(str);
res=0;
cnt_k=0;
int j=0;
for(int i=0;i<len;i++)
{
int cur_str=str[i]-'a';
if(cnt[cur_str]==0)
{
cnt[cur_str]++;
cnt_k++;
if(cnt_k==k)
{
res+=len-i;
while(j<=i)
{
cnt[str[j]-'a']--;
if(cnt[str[j]-'a']==0)
{
j++;
cnt_k--;
break;
}
else
{
res+=len-i;
}
j++;
}
}
}
else
cnt[cur_str]++;
}
printf("%lld\n",res);
}
return 0;
}