LeetCode 题解工作台

元音辅音字符串计数 I

给你一个字符串 word 和一个 非负 整数 k 。 返回 word 的 子字符串 中,每个元音字母( 'a' 、 'e' 、 'i' 、 'o' 、 'u' ) 至少 出现一次,并且 恰好 包含 k 个辅音字母的子字符串的总数。 示例 1: 输入: word = "aeioqq", k = 1 输…

category

3

题型

code_blocks

6

代码语言

hub

3

相关题

当前训练重点

中等 · 滑动窗口(状态滚动更新)

bolt

答案摘要

我们可以转换为求以下两个问题: 1. 求每个元音字母至少出现一次,且至少包含 个辅音字母的子字符串的总数 ;

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 滑动窗口(状态滚动更新) 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个字符串 word 和一个 非负 整数 k

返回 word子字符串 中,每个元音字母('a''e''i''o''u'至少 出现一次,并且 恰好 包含 k 个辅音字母的子字符串的总数。

 

示例 1:

输入:word = "aeioqq", k = 1

输出:0

解释:

不存在包含所有元音字母的子字符串。

示例 2:

输入:word = "aeiou", k = 0

输出:1

解释:

唯一一个包含所有元音字母且不含辅音字母的子字符串是 word[0..4],即 "aeiou"

示例 3:

输入:word = "ieaouqqieaouqq", k = 1

输出:3

解释:

包含所有元音字母并且恰好含有一个辅音字母的子字符串有:

  • word[0..5],即 "ieaouq"
  • word[6..11],即 "qieaou"
  • word[7..12],即 "ieaouq"

 

提示:

  • 5 <= word.length <= 250
  • word 仅由小写英文字母组成。
  • 0 <= k <= word.length - 5
lightbulb

解题思路

方法一:问题转换 + 滑动窗口

我们可以转换为求以下两个问题:

  1. 求每个元音字母至少出现一次,且至少包含 kk 个辅音字母的子字符串的总数 f(k)\textit{f}(k)
  2. 求每个元音字母至少出现一次,且至少包含 k+1k + 1 个辅音字母的子字符串的总数 f(k+1)\textit{f}(k + 1)

那么答案就是 f(k)f(k+1)\textit{f}(k) - \textit{f}(k + 1)

因此,我们设计一个函数 f(k)\textit{f}(k),用于统计每个元音字母至少出现一次,且至少包含 kk 个辅音字母的子字符串的总数。

我们可以用一个哈希表 cnt\textit{cnt} 统计每个元音字母的出现次数,用一个变量 ans\textit{ans} 统计答案,用一个变量 l\textit{l} 记录滑动窗口的左边界,用一个变量 x\textit{x} 记录当前窗口中辅音字母的个数。

遍历字符串,如果当前字符是元音字母,则将其加入哈希表 cnt\textit{cnt} 中,否则将 x\textit{x} 加一。如果此时 xk\textit{x} \ge k 且哈希表 cnt\textit{cnt} 的大小为 55,说明当前窗口满足条件,我们循环移动左边界,直到窗口不满足条件。此时,以右边界 r\textit{r} 为结尾、且左边界在 [0,..l1][0,.. \textit{l} - 1] 范围内的子字符串都满足条件,一共有 l\textit{l} 个。我们将 l\textit{l} 加到答案中。继续遍历字符串,直到遍历结束,我们就得到了 f(k)\textit{f}(k)

最后,我们返回 f(k)f(k+1)\textit{f}(k) - \textit{f}(k + 1)

时间复杂度 O(n)O(n),其中 nn 是字符串 word\textit{word} 的长度。空间复杂度 O(1)O(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution:
    def countOfSubstrings(self, word: str, k: int) -> int:
        def f(k: int) -> int:
            cnt = Counter()
            ans = l = x = 0
            for c in word:
                if c in "aeiou":
                    cnt[c] += 1
                else:
                    x += 1
                while x >= k and len(cnt) == 5:
                    d = word[l]
                    if d in "aeiou":
                        cnt[d] -= 1
                        if cnt[d] == 0:
                            cnt.pop(d)
                    else:
                        x -= 1
                    l += 1
                ans += l
            return ans

        return f(k) - f(k + 1)
speed

复杂度分析

指标
时间complexity is O(n) for sliding through the string with constant-time hash map updates per letter. Space complexity is O(1) for the hash map since vowels are limited and consonant counting uses constant space.
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Check that all vowels exist before counting the substring.

  • question_mark

    Watch for off-by-one errors when managing the window boundaries.

  • question_mark

    Confirm consonant count matches exactly k while expanding or shrinking.

warning

常见陷阱

外企场景
  • error

    Forgetting to remove consonants when shrinking the window.

  • error

    Counting windows that include all vowels but exceed k consonants.

  • error

    Using nested loops for substring generation instead of sliding window.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Count substrings containing all vowels and at most k consonants.

  • arrow_right_alt

    Count substrings containing all vowels and a range of consonants from k to m.

  • arrow_right_alt

    Count substrings containing all vowels and exactly k specific consonants only.

help

常见问题

外企场景

元音辅音字符串计数 I题解:滑动窗口(状态滚动更新) | LeetCode #3305 中等