其他系列文章导航
这是力扣的 1456 题,难度为中等,解题方案有很多种,本文讲解我认为最奇妙的一种。
又是一道滑动窗口的典型例题,可以帮助我们巩固滑动窗口算法。
给你字符串?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
思路与算法:
首先定义一个 list 来存放元音字母,可以用 list 自带的 api :contains 来判断是否包含。
还需要定义两个变量:
然后设置初始窗口,那我们就在数组最前方取 k 个元素当作窗口。
记录下初始窗口的元音数量,并先存为最大值。
接着开始滑动窗口:
每次循环完后记录下最大元音数量。
思路与算法:
这个方法在第一个方法的基础上,做了一个简单的优化:
如果窗口里已经全部都是元音了,没必要把后面的都遍历一遍,我们已经得到结果了不是吗?
k 比较小的时候可能大大减少遍历的位置!!!!
当当前元音数量等于 k 的时候,我们直接返回 k 。
Java版本:
class Solution {
public int maxVowels(String s, int k) {
ArrayList<Character> list = new ArrayList<>(Arrays.asList('a', 'e', 'i', 'o', 'u'));
int vowels = 0, maxVowels;
for (int i = 0; i < k; i++) {
if (list.contains(s.charAt(i))) {
vowels++;
}
}
maxVowels = vowels;
for (int i = k; i < s.length(); i++) {
if (list.contains(s.charAt(i - k))) {
vowels--;
}
if (list.contains(s.charAt(i))) {
vowels++;
}
maxVowels = Math.max(vowels, maxVowels);
}
return maxVowels;
}
}
C++版本:
class Solution {
public:
int maxVowels(string s, int k) {
vector<char> vowels = {'a', 'e', 'i', 'o', 'u'};
int maxVowels = 0, currentVowels = 0;
for (int i = 0; i < k; i++) {
if (find(vowels.begin(), vowels.end(), s[i]) != vowels.end()) {
currentVowels++;
}
}
maxVowels = currentVowels;
for (int i = k; i < s.length(); i++) {
if (find(vowels.begin(), vowels.end(), s[i - k]) != vowels.end()) {
currentVowels--;
}
if (find(vowels.begin(), vowels.end(), s[i]) != vowels.end()) {
currentVowels++;
}
maxVowels = max(currentVowels, maxVowels);
}
return maxVowels;
}
};
Java版本:
class Solution {
public int maxVowels(String s, int k) {
ArrayList<Character> list = new ArrayList<>(Arrays.asList('a', 'e', 'i', 'o', 'u'));
int vowels = 0, maxVowels;
for (int i = 0; i < k; i++) {
if (list.contains(s.charAt(i))) {
vowels++;
}
}
if (vowels == k) return k;
maxVowels = vowels;
for (int i = k; i < s.length(); i++) {
if (list.contains(s.charAt(i - k))) {
vowels--;
}
if (list.contains(s.charAt(i))) {
vowels++;
}
if (vowels == k) return k;
maxVowels = Math.max(vowels, maxVowels);
}
return maxVowels;
}
}
C++版本:
class Solution {
public:
int maxVowels(std::string s, int k) {
std::vector<char> list = {'a', 'e', 'i', 'o', 'u'};
int vowels = 0, maxVowels;
for (int i = 0; i < k; i++) {
if (std::find(list.begin(), list.end(), s[i]) != list.end()) {
vowels++;
}
}
if (vowels == k) return k;
maxVowels = vowels;
for (int i = k; i < s.length(); i++) {
if (std::find(list.begin(), list.end(), s[i - k]) != list.end()) {
vowels--;
}
if (std::find(list.begin(), list.end(), s[i]) != list.end()) {
vowels++;
}
if (vowels == k) return k;
maxVowels = std::max(vowels, maxVowels);
}
return maxVowels;
}
};