一、题目
There is a string S only contain lower case English character.(10 < length(S) < 1,000,000) How many substrings there are that contain at least k(1 ≤ k ≤ 26) distinct characters?
Input:
There are multiple test cases. The first line of input contains an integer T T(1 ≤ T ≤ 10) indicating the number of test cases. For each test case:
The first line contains string SS. The second line contains a integer k(1 ≤ k ≤ 26).
Output:
For each test case, output the number of substrings that contain at least kk dictinct characters.
Inputcopy:
2
abcabcabca
4
abcabcabcabc
3
Outputcopy:
0
55
二、方法一
1、思路
利用了桶的思想:用一个数组来存储字符的出现次数。
注意:
如果指针右移使此字母 出现, num 值就加一;
如果指针左移使此字母 消失, num 值就减一。
直到遍历完成后结束。
2、代码
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#define max 1000005
char s[max];
int t, k;
int i, j;
int left, right, len, num; // num:不同字符的个数
long long int sum; // sum:字符串的个数
int a[30];
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%s", s);
scanf("%d", &k);
left = 0, right = 0, num = 0, sum = 0;
memset(a, 0, sizeof(a));
len = strlen(s);
// 确保左指针右侧有k个字符
while (left <= len - k)
{
// 当找到k的不同字符串 或 遍历完成后结束循环
while (num < k && right < len)
{
// 桶的思想
if (a[s[right] - 'a'] == 0)
{
num++;
}
a[s[right] - 'a']++;
right++;
}
// 找到k的不同字符串
if (num == k)
sum += len - right + 1;
// 左指针左移
a[s[left] - 'a']--;
// 如果左移使此字母的次数由一变成零, num 值就减一
if (a[s[left] - 'a'] == 0)
num--;
left++;
}
printf("%lld\n", sum);
}
return 0;
}