Leetcode 1456. Maximum Number of Vowels in a Substring of Given Length
问题理解
给定一个字符串 s 和一个整数 k,要求找出 长度恰好为 k 的连续子串中,包含最多元音字母(a, e, i, o, u,不区分大小写)的个数。
- 元音字母:
a, e, i, o, u(含大小写) - 子串必须 连续且长度严格等于
k - 目标:返回所有满足条件的子串中,元音数量的最大值
示例:输入:s = "leetcode", k = 3输出:2(子串 "lee" 或 "ode" 含 2 个元音)
解题思路:滑动窗口(Sliding Window)
由于子串长度固定为 k,非常适合使用 固定大小的滑动窗口:
- 初始化:计算第一个窗口
[0, k-1]中的元音数量。 - 滑动:窗口每次右移一位:
- 移出左边字符(索引
i - k) - 移入右边字符(索引
i) - 根据这两个字符是否为元音,动态更新当前窗口的元音计数
- 移出左边字符(索引
- 记录最大值:每一步更新全局最大元音数。
时间复杂度:O(n)空间复杂度:O(1)
Trick
-
错误写法(常见陷阱):
if(vowels.find(c)){...}// 危险!string::find()返回 索引(找到时 ≥0,未找到时为string::npos)- 当字符是
'a'时,find返回0→if(0)为false→ 漏判元音 - 当字符不是元音时,
find返回npos(一个很大的无符号数)→if(npos)为true→ 误判为元音
结果:只有 'a' 被当成非元音,其他所有字符(包括辅音)都被当成元音!
-
正确判断方式:
// 方法1:显式比较 bool isVowel(char c){ return vowels.find(c)!= string::npos; } // 方法2:直接枚举(更高效、清晰) bool isVowel(char c){ return c=='a'|| c=='e'|| c=='i'|| c=='o'|| c=='u'|| c=='A'|| c=='E'|| c=='I'|| c=='O'|| c=='U'; } -
滑动窗口更新逻辑:
cpp
编辑
// 窗口从 [i-k, i-1] 移动到 [i-k+1, i] if(isVowel(s[i]) && !isVowel(s[i - k])) curr++;// 新加入的是元音, 且移出的不是元音 if(!isVowel(s[i]) && isVowel(s[i - k])) curr--;// 被移出的是元音,且新加入的不是元音注意:两个判断 独立进行,不能用 else if!
Code
class Solution {
public:
int maxVowels(string s, int k) {
int max = 0, curr = 0;
int i = 0;
while(i < s.length())
{
if(i < k) {
if(is_vowel(s[i])) curr++;
}
else {
if(is_vowel(s[i]) && !is_vowel(s[i-k])) curr++;
if(!is_vowel(s[i]) && is_vowel(s[i-k])) curr--;
}
if(curr > max) max = curr;
i++;
}
return max;
}
bool is_vowel(char c){
string vowel = "aeiouAEIOU";
if(vowel.find(c) != string::npos){
return 1;
}
return 0;
}
};

浙公网安备 33010602011771号