内容持续更新…(始于2024年08月19日)
1.问题
Given a string s and an integer k, return the maximum number of vowel letters in any substring of s with length k.
Vowel letters in English are ‘a’, ‘e’, ‘i’, ‘o’, and ‘u’.
Constraints:
1 <= s.length <= 105
s consists of lowercase English letters.
1 <= k <= s.length# 2. 解题思路
方法1:
-
滑动窗口初始化:首先,计算第一个长度为 k 的子串中的元音数量,并设置为当前窗口的元音总数。
-
滑动窗口技术:
- 移动窗口时,删除窗口开头的字符,并检查是否是元音。
- 添加窗口末尾的新字符,并检查是否是元音。
- 更新当前窗口的元音数量,并与 maxVowels 进行比较,保持记录最大值。
- 时间复杂度:此方法的时间复杂度为 O(n),其中 n 是字符串的长度,因为每个字符只被访问和处理一次。
3. 代码
代码1:
class Solution {
public static boolean isVowel(char c) {
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
public int maxVowels(String s, int k) {
// 获取字符串的长度
int n = s.length();
// 初始化最大元音数量
int maxVowels = 0;
int currentVowels = 0;
// 计算第一个窗口内的元音数量
for (int i = 0; i < k; i++) {
if (isVowel(s.charAt(i))) {
currentVowels++;
}
}
// 记录第一个窗口的最大元音数量
maxVowels = currentVowels;
// 使用滑动窗口技术,移动窗口并更新最大元音数量
for (int i = k; i < n; i++) {
// 删除窗口的开头字符
if (isVowel(s.charAt(i - k))) {
currentVowels--;
}
// 添加窗口的新字符
if (isVowel(s.charAt(i))) {
currentVowels++;
}
// 更新最大元音数量
maxVowels = Math.max(maxVowels, currentVowels);
}
return maxVowels;
}
}
假设我们有一个字符串 s = “abciiidef”,并且 k = 3。我们的目标是找到所有长度为 k 的子串中,包含的最大元音字母数量。
- 步骤1:初始化
s = “abciiidef”
k = 3
n = 8(字符串的长度)
初始窗口:s.substring(0, 3) = “abc”
元音数量:a(1个) - 步骤2:计算第一个窗口的元音数量
窗口 “abc”:包含的元音数量为 1。
设置 currentVowels = 1,maxVowels = 1。 - 步骤3:滑动窗口
窗口移到 “bci”
删除字符 ‘a’,它是元音,所以 currentVowels–,currentVowels = 0。
添加字符 ‘i’,它是元音,所以 currentVowels++,currentVowels = 1。
更新 maxVowels = max(maxVowels, currentVowels) = max(1, 1) = 1。
窗口移到 “cii”
-
删除字符 ‘b’,它不是元音,所以 currentVowels 不变。
-
添加字符 ‘i’,它是元音,所以 currentVowels++,currentVowels = 2。
-
更新 maxVowels = max(maxVowels, currentVowels) = max(1, 2) = 2。
窗口移到 “iii” -
删除字符 ‘c’,它不是元音,所以 currentVowels 不变。
-
添加字符 ‘i’,它是元音,所以 currentVowels++,currentVowels = 3。
-
更新 maxVowels = max(maxVowels, currentVowels) = max(2, 3) = 3。
-
窗口移到 “iii”(同样的窗口,不需要重新计算)
窗口移到 “iide”
-
删除字符 ‘i’,它是元音,所以 currentVowels–,currentVowels = 2。
-
添加字符 ‘e’,它是元音,所以 currentVowels++,currentVowels = 3。
-
更新 maxVowels = max(maxVowels, currentVowels) = max(3, 3) = 3。
窗口移到 “idef” -
删除字符 ‘i’,它是元音,所以 currentVowels–,currentVowels = 2。
-
添加字符 ‘f’,它不是元音,所以 currentVowels 不变。
-
更新 maxVowels = max(maxVowels, currentVowels) = max(3, 2) = 3。
结果
最大的元音数量在长度为 3 的子串中是 3,出现在子串 “iii” 中。
总结
通过滑动窗口技术,每次移动窗口时,删除窗口开头的字符并添加窗口末尾的新字符,可以高效地计算每个窗口内的元音数量。这种方法避免了重复计算,从而提高了效率。