C语言算法题:String

一、题目

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WE-ubytt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值