跳转至

2062. 统计字符串中的元音子字符串

题目描述

子字符串 是字符串中的一个连续(非空)的字符序列。

元音子字符串 由元音('a''e''i''o''u')组成的一个子字符串,且必须包含 全部五种 元音。

给你一个字符串 word ,统计并返回 word元音子字符串的数目

 

示例 1:

输入:word = "aeiouu"
输出:2
解释:下面列出 word 中的元音子字符串(斜体加粗部分):
- "aeiouu"
- "aeiouu"

示例 2:

输入:word = "unicornarihan"
输出:0
解释:word 中不含 5 种元音,所以也不会存在元音子字符串。

示例 3:

输入:word = "cuaieuouac"
输出:7
解释:下面列出 word 中的元音子字符串(斜体加粗部分):
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"

示例 4:

输入:word = "bbaeixoubb"
输出:0
解释:所有包含全部五种元音的子字符串都含有辅音,所以不存在元音子字符串。

 

提示:

  • 1 <= word.length <= 100
  • word 仅由小写英文字母组成

解法

方法一:暴力枚举 + 哈希表

我们可以枚举子字符串的左端点 $i$,对于当前左端点,维护一个哈希表,记录当前子字符串中出现的元音字母,然后枚举右端点 $j$,如果当前右端点对应的字母不是元音字母,则跳出循环,否则将当前右端点对应的字母加入哈希表,如果哈希表中的元素个数为 $5$,则说明当前子字符串是一个元音子字符串,将结果加 $1$。

时间复杂度 $O(n^2)$,空间复杂度 $O(C)$。其中 $n$ 为字符串 $word$ 的长度;而 $C$ 为字符集大小,本题中 $C=5$。

1
2
3
4
5
class Solution:
    def countVowelSubstrings(self, word: str) -> int:
        n = len(word)
        s = set('aeiou')
        return sum(set(word[i:j]) == s for i in range(n) for j in range(i + 1, n + 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 {
    public int countVowelSubstrings(String word) {
        int n = word.length();
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            Set<Character> t = new HashSet<>();
            for (int j = i; j < n; ++j) {
                char c = word.charAt(j);
                if (!isVowel(c)) {
                    break;
                }
                t.add(c);
                if (t.size() == 5) {
                    ++ans;
                }
            }
        }
        return ans;
    }

    private boolean isVowel(char c) {
        return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
    int countVowelSubstrings(string word) {
        int ans = 0;
        int n = word.size();
        for (int i = 0; i < n; ++i) {
            unordered_set<char> t;
            for (int j = i; j < n; ++j) {
                char c = word[j];
                if (!isVowel(c)) break;
                t.insert(c);
                ans += t.size() == 5;
            }
        }
        return ans;
    }

    bool isVowel(char c) {
        return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
func countVowelSubstrings(word string) int {
    ans, n := 0, len(word)
    for i := range word {
        t := map[byte]bool{}
        for j := i; j < n; j++ {
            c := word[j]
            if !(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
                break
            }
            t[c] = true
            if len(t) == 5 {
                ans++
            }
        }
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
function countVowelSubstrings(word: string): number {
    let ans = 0;
    const n = word.length;
    for (let i = 0; i < n; ++i) {
        const t = new Set<string>();
        for (let j = i; j < n; ++j) {
            const c = word[j];
            if (!(c === 'a' || c === 'e' || c === 'i' || c === 'o' || c === 'u')) {
                break;
            }
            t.add(c);
            if (t.size === 5) {
                ans++;
            }
        }
    }
    return ans;
}

方法二

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution:
    def countVowelSubstrings(self, word: str) -> int:
        s = set('aeiou')
        ans, n = 0, len(word)
        for i in range(n):
            t = set()
            for c in word[i:]:
                if c not in s:
                    break
                t.add(c)
                ans += len(t) == 5
        return ans

评论