leetcode:定长字串中元音的最大数目

定长字串中元音的最大数目

medium

给你字符串 s 和整数 k

请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。

英文中的 元音字母 为(a, e, i, o, u)。

示例 1:

输入:s = "abciiidef", k = 3
输出:3
解释:子字符串 "iii" 包含 3 个元音字母。

示例 2:

输入:s = "aeiou", k = 2
输出:2
解释:任意长度为 2 的子字符串都包含 2 个元音字母。

示例 3:

输入:s = "leetcode", k = 3
输出:2
解释:"lee"、"eet" 和 "ode" 都包含 2 个元音字母。

示例 4:

输入:s = "rhythms", k = 4
输出:0
解释:字符串 s 中不含任何元音字母。

示例 5:

输入:s = "tryhard", k = 4
输出:1

提示:

  • 1 <= s.length <= 10^5
  • s 由小写英文字母组成
  • 1 <= k <= s.length

解题思路
本题最简单的思路就是滑动窗口,每次滑动向后滑动一个位置。而每滑动一次,只涉及两个字符的变动,即:

本次滑动新加进来的字符是否是元音
本次滑动去掉的字符是否是元音

image-20230716183243331

示例: 1、假设当前窗口的元音个数是n,那么在滑动时

如果当前窗口的起始位置是元音,那么传递到下一个窗口的元音个数m = n - 1
如果当前窗口的起始位置不是元音,那么传递到下一个窗口的元音个数就是m = n
2、接着,下一个窗口判断新加进来的元素是否是元音。 如果是,则下一个窗口的元音个数就是m + 1,否则为m

3、每个窗口判断当前元音个数tmp是否大于截止当前的最大值result,如果是则result = tmp 4、继续下一个窗口计算

有一个优化点:如果当前窗口的元音个数= k,其实就没必要再继续滑动了,直接return

复杂度分析
时间复杂度:O(n)
只需要最多遍历一遍所有字符

空间复杂度:O(1)
只需要常数空间来存储几个常量

代码
理解了原理,代码就很简单了

普通版:(时间很慢未超时)

class Solution:
    def maxVowels(self, s: str, k: int) -> int:
        start = maxvowels = _vowels = 0
        vowels = {'a', 'e', 'i', 'o', 'u'}
        for i, char in enumerate(s):
            cursor = s[start: i + 1]
            if len(cursor) <= k:
                if s[i] in vowels:
                    _vowels += 1
            else:
                start += 1
                if s[start - 1] in vowels:
                    _vowels -= 1
                if s[i] in vowels:
                    _vowels += 1
            maxvowels = max(_vowels, maxvowels)
        return maxvowels

优化版:(时间很快)

class Solution:
    def maxVowels(self, s: str, k: int) -> int:
        sid, tmp = 0, 0 # 第一个滑动窗口起始位置,当前窗口元音字符个数
        fid = k - 1 # 第一个滑动窗口结束位置
        mapping = {"a":1, "e":1, "i":1, "o":1, "u":1}
        for i in range(fid): # 第一个窗口现在外面判断
            if s[i] in mapping:
                tmp += 1 
        result = tmp 
        while fid < len(s):
            if s[fid] in mapping: # 判断窗口往后移动的这个元素是否是元音
                tmp += 1 # 如果是元音,则判断当前窗口元音个数与当前结果的大小
                result = tmp  if tmp > result else result
                if tmp >= k: # 如果当前窗口的元音数=k,则直接返回
                    return k 
            if s[sid] in mapping: # 判断当前窗口起始位置是否是元音
                tmp -= 1 # 将窗口起始位置的元音减去再滑动到下一个窗口
            sid += 1 #窗口向后滑动一个元素
            fid += 1 
        return result
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Franda914

有钱的捧个钱场,没钱的点的赞

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

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

打赏作者

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

抵扣说明:

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

余额充值