LeetCode 1456. 定长子串中元音的最大数目
题目链接
1456. 定长子串中元音的最大数目
题目描述
给定一个字符串 s
和一个整数 k
,请找出字符串中长度为 k
的子串中包含的最大元音字母数量。元音字母包括 a
、e
、i
、o
、u
。
解法分析:滑动窗口法
核心思路
该解法采用滑动窗口技术,通过维护一个长度为 k
的窗口,遍历字符串时动态计算窗口内的元音字母数量,从而找到最大值。具体步骤如下:
- 右指针扩展窗口,统计当前字符是否为元音并累加计数
- 当窗口长度达到
k
后,左指针开始滑动,每次移除窗口左边界的字符 - 实时更新窗口内元音字母的最大数量
代码实现
class Solution:def maxVowels(self, s: str, k: int) -> int:l = 0 # 左指针cnt = 0 # 当前窗口内元音字母数量ans = 0 # 最大元音字母数量for r in range(len(s)):# 统计当前字符是否为元音,是则cnt加1cnt += 1 if s[r] in "aeiou" else 0# 当窗口长度达到k时,开始滑动窗口if r + 1 >= k:ans = max(ans, cnt) # 更新最大值cnt -= 1 if s[l] in "aeiou" else 0 # 移除左边界字符的计数l += 1 # 左指针右移,窗口滑动return ans
代码解析
-
初始化变量:
l
:滑动窗口的左指针,初始位置为0cnt
:记录当前窗口内的元音字母数量,初始为0ans
:记录最大元音字母数量,初始为0
-
遍历字符串:
- 右指针
r
从0开始遍历每个字符 cnt += 1 if s[r] in "aeiou" else 0
:判断当前字符是否为元音,若是则cnt
加1
- 右指针
-
窗口滑动逻辑:
- 当
r + 1 >= k
时,说明窗口长度已达到k
(索引从0开始,r+1
表示当前窗口长度) ans = max(ans, cnt)
:更新当前窗口内元音字母的最大数量cnt -= 1 if s[l] in "aeiou" else 0
:减去左边界字符的元音计数l += 1
:左指针右移,窗口向右滑动一位
- 当
-
结果返回:
- 遍历结束后,
ans
即为所有长度为k
的子串中元音字母的最大数量
- 遍历结束后,
关键逻辑说明
- 窗口长度控制:通过
r + 1 >= k
判断窗口是否达到指定长度,确保窗口始终保持长度为k
- 动态计数:每次窗口滑动时,仅需更新左边界字符的计数,避免重新计算整个窗口
- 时间优化:滑动窗口技术使得每个字符仅被访问两次(进入和离开窗口时),时间复杂度为线性
复杂度分析
- 时间复杂度:O(n),其中
n
是字符串长度。右指针遍历字符串一次,左指针最多移动n
次,总操作次数为 O(n)。 - 空间复杂度:O(1),仅使用常数级额外空间存储指针和计数变量。
示例详解
以输入 s = "abciiidef", k = 3
为例:
-
初始化:
l=0, cnt=0, ans=0
-
r=0,字符’a’:
a
是元音,cnt=1
r+1=1 < 3
,不滑动窗口
-
r=1,字符’b’:
b
不是元音,cnt=1
r+1=2 < 3
,不滑动窗口
-
r=2,字符’c’:
c
不是元音,cnt=1
r+1=3 >= 3
,进入滑动:ans = max(0, 1) = 1
s[l=0]='a'
是元音,cnt=1-1=0
l=1
-
r=3,字符’i’:
i
是元音,cnt=0+1=1
r+1=4 >= 3
:ans = max(1, 1) = 1
s[l=1]='b'
不是元音,cnt=1-0=1
l=2
-
r=4,字符’i’:
i
是元音,cnt=1+1=2
r+1=5 >= 3
:ans = max(1, 2) = 2
s[l=2]='c'
不是元音,cnt=2-0=2
l=3
-
r=5,字符’i’:
i
是元音,cnt=2+1=3
r+1=6 >= 3
:ans = max(2, 3) = 3
s[l=3]='i'
是元音,cnt=3-1=2
l=4
-
r=6,字符’d’:
d
不是元音,cnt=2+0=2
r+1=7 >= 3
:ans = max(3, 2) = 3
s[l=4]='i'
是元音,cnt=2-1=1
l=5
-
r=7,字符’e’:
e
是元音,cnt=1+1=2
r+1=8 >= 3
:ans = max(3, 2) = 3
s[l=5]='i'
是元音,cnt=2-1=1
l=6
-
r=8,字符’f’:
f
不是元音,cnt=1+0=1
r+1=9 >= 3
:ans = max(3, 1) = 3
s[l=6]='d'
不是元音,cnt=1-0=1
l=7
-
最终返回
3
,对应子串"iii"
(索引3-5)。
总结
该解法利用滑动窗口高效解决了定长子串的元音计数问题,核心在于维护固定长度的窗口并动态更新计数。滑动窗口技术在此类问题中具有显著优势:
- 避免了暴力枚举所有子串的O(n²)复杂度
- 通过双指针移动实现线性时间复杂度
- 仅需常数空间存储临时变量
此方法适用于所有"定长子串统计"问题,如子串中特定字符计数、子串和计算等,是算法设计中的基础技巧。