2063. 所有子字符串中的元音

统计所有子字符串中元音的总数 — 高效解法详解

题目描述

给定一个字符串 word,返回它所有 子字符串元音 的总数。
元音指的是 'a''e''i''o''u'

  • 子字符串 指的是字符串中连续的非空字符序列。
  • 输入字符串由小写英文字母组成,长度范围为 1 <= word.length <= 10^5
  • 由于答案可能超过 32 位整数范围,需要用更大的数据类型处理。

示例说明

示例 1

输入:word = "aba"
所有子字符串有:

"a", "ab", "aba", "b", "ba", "a"

计算每个子字符串中元音数量:

  • "a" → 1 个元音
  • "ab" → 1 个元音
  • "aba" → 2 个元音
  • "b" → 0 个元音
  • "ba" → 1 个元音
  • "a" → 1 个元音

元音总数 = 1 + 1 + 2 + 0 + 1 + 1 = 6


示例 2

输入:word = "abc"
子字符串:

"a", "ab", "abc", "b", "bc", "c"

元音数:

  • "a" → 1
  • "ab" → 1
  • "abc" → 1
  • "b" → 0
  • "bc" → 0
  • "c" → 0

总和 = 3


示例 3

输入:word = "ltcd"
所有子字符串均不含元音,因此总和为 0。


示例 4

输入:word = "noosabasboosa"
输出:237 (题目给出的正确结果)


解题分析

直接枚举所有子字符串,计算每个子字符串内元音数的方法,时间复杂度约为 O(n²)(字符串长度 n 最高可达 10^5),显然不可行。

因此,我们需要寻找更高效的方法。


关键思路

  • 注意到每个元音字符对结果的贡献是独立的。
  • 具体来说,对于字符串长度为 n 的字符串中,假设第 i 个字符是元音。
  • 这个字符能够被多少个子字符串包含呢?

举例说明:

字符串索引从 0 开始,到 n-1。

  • 子字符串的起点可以从 [0 ... i] 选择,共有 i + 1 种选择。
  • 子字符串的终点可以从 [i ... n - 1] 选择,共有 n - i 种选择。

因此,包含索引 i 处字符的子字符串总数是:

(i + 1) * (n - i)

因为这个字符是元音,它在所有包含它的子字符串中都会贡献 1 个元音。所以元音总数的贡献就是这个数。


解题方法

将字符串中所有元音字符的位置分别计算贡献,并累加。

代码实现(Python)

class Solution:
    def countVowels(self, word: str) -> int:
        vowels = set('aeiou')
        n = len(word)
        total = 0
        for i, ch in enumerate(word):
            if ch in vowels:
                total += (i + 1) * (n - i)
        return total

复杂度分析

  • 时间复杂度:O(n),只遍历一次字符串即可。
  • 空间复杂度:O(1),只使用了常数额外空间。

示例再验证

以示例 "aba" 为例:

  • i=0,字符 'a',贡献 (0+1)*(3-0) = 1*3 = 3
  • i=1,字符 'b',非元音,贡献 0
  • i=2,字符 'a',贡献 (2+1)*(3-2) = 3*1 = 3

总贡献 = 3 + 0 + 3 = 6,与示例答案一致。


方法优劣对比

方法时间复杂度是否可行(n=10^5)说明
枚举所有子串计数O(n²)不可行子串数量达 O(n²),超时严重。
按元音贡献计算O(n)可行只遍历一次字符串,效率极高。

总结

  • 该问题的核心是理解每个元音字符在所有子串中的出现次数。
  • 利用数学推导避免暴力枚举,使问题复杂度从 O(n²) 降至 O(n)。
  • 该思路也适合解决类似“字符贡献总和”的题目。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值