题目是LeetCode第190场周赛的第二题,链接:1456. 定长子串中元音的最大数目。具体描述为:给你字符串s
和整数k
。请返回字符串s
中长度为k
的单个子字符串中可能包含的最大元音字母数。英文中的元音字母为(a
, e
, i
, o
, u
)。
1 <= s.length <= 10^5
s
由小写英文字母组成1 <= k <= s.length
示例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
题目也不难,就是普通的滑动窗口的题目嘛,就用一个长度为k
的窗口,一个sum
记录窗口内的元音字母总数量,滑动过程中看进入窗口和退出窗口的这两个字母是否为元音字母,相应地改变sum
,最后返回这个过程中sum
的最大值即可。注意这个过程中需要修改sum
的只有两种情况,也就是进入窗口的为元音字母且出窗口的非元音字母或者进入窗口的非元音字母但出窗口的为元音字母,其他情况下sum
的值不用改变。时间复杂度为
O
(
n
)
O(n)
O(n),空间复杂度为
O
(
1
)
O(1)
O(1)。
JAVA版代码如下:
class Solution {
public int maxVowels(String s, int k) {
int[] index = new int[26];
Arrays.fill(index, -1);
index['a' - 'a'] = 0;
index['e' - 'a'] = 1;
index['i' - 'a'] = 2;
index['o' - 'a'] = 3;
index['u' - 'a'] = 4;
char[] chars = s.toCharArray();
int left = 0, right = 0;
int sum = 0;
for (; right < k; ++right) {
int idx = index[chars[right] - 'a'];
if (idx!= -1) {
++sum;
}
}
int result = sum;
for (; right < chars.length; ++right) {
int leftIdx = index[chars[left] - 'a'];
int rightIdx = index[chars[right] - 'a'];
if (leftIdx != -1 && rightIdx == -1) {
--sum;
}
else if (rightIdx != -1 && leftIdx == -1) {
++sum;
result = Math.max(result, sum);
}
++left;
}
return result;
}
}
提交结果如下:
Python版代码如下:
class Solution:
def maxVowels(self, s: str, k: int) -> int:
index = [-1] * 26
base = ord('a')
index[ord('a') - base] = 0
index[ord('e') - base] = 1
index[ord('i') - base] = 2
index[ord('o') - base] = 3
index[ord('u') - base] = 4
curSum = 0
for i in range(k):
idx = index[ord(s[i]) - base]
if idx != -1:
curSum += 1
result = curSum
for i in range(k, len(s)):
left = index[ord(s[i - k]) - base]
right = index[ord(s[i]) - base]
if left == -1 and right != -1:
curSum += 1
result = max(curSum, result)
elif left != -1 and right == -1:
curSum -= 1
return result
提交结果如下: