📜  恰好包含 K 个元音的子串计数(1)

📅  最后修改于: 2023-12-03 15:09:55.742000             🧑  作者: Mango

恰好包含 K 个元音的子串计数

这是一个计算字符串中恰好包含 K 个元音的子串数量的问题。

问题描述

给定一个包含小写英文字母的字符串,计算其中恰好包含 K 个元音字母的子串数量。

元音字母有五个:a,e,i,o,u。

解决方案
暴力法

我们可以使用两层循环遍历所有子串,然后统计其中元音字母的数量。如果数量等于 K,则计数器加一。

时间复杂度为 O(n^3),不适合处理大规模数据。

滑动窗口

我们可以使用滑动窗口来优化暴力法。

窗口内维护一个恰好包含 K 个元音的子串。我们先将窗口移动到 K 个字符处,统计此时窗口内元音字母的数量,如果数量等于 K,则计数器加一。

然后,每次将窗口右移一个位置,同时更新窗口内元音字母的数量。如果数量等于 K,则计数器加一。

时间复杂度为 O(n),适合处理大规模数据。

前缀和

如果我们预处理出字符串中每个位置之前恰好包含 0, 1, 2, ..., K 个元音字母的子串数量,则可以在 O(1) 时间内计算出任意一个子串中恰好包含 K 个元音字母的数量。

具体实现可以使用前缀和的思想。

时间复杂度为 O(n),适合处理大规模数据。

代码示例
滑动窗口
def count_k_vowel_substrings(s: str, k: int) -> int:
    vowels = {'a', 'e', 'i', 'o', 'u'}
    n = len(s)
    left, right = 0, k - 1
    count = 0
    cur_count = sum(1 for c in s[left:right+1] if c in vowels)
    while right < n:
        if cur_count == k:
            count += 1
        if right == n - 1:
            break
        right += 1
        cur_count += 1 if s[right] in vowels else 0
        cur_count -= 1 if s[left] in vowels else 0
        left += 1
    return count
前缀和
def count_k_vowel_substrings(s: str, k: int) -> int:
    vowels = {'a', 'e', 'i', 'o', 'u'}
    n = len(s)
    count = [0] * (k+1)
    count[0] = 1
    cur_count = 0
    for i in range(n):
        cur_count += 1 if s[i] in vowels else 0
        if cur_count >= k:
            count[cur_count] += count[cur_count-k]
        count[cur_count] += 1
    return count[k] if k > 0 else sum(count)