题目简介:
给你字符串 s 和整数 k 。
请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。
英文中的 元音字母 为(a, e, i, o, u)。
示例 1:
1 2 3
| 输入:s = "abciiidef", k = 3 输出:3 解释:子字符串 "iii" 包含 3 个元音字母。
|
示例 2:
1 2 3
| 输入:s = "aeiou", k = 2 输出:2 解释:任意长度为 2 的子字符串都包含 2 个元音字母。
|
示例 3:
1 2 3
| 输入:s = "leetcode", k = 3 输出:2 解释:"lee"、"eet" 和 "ode" 都包含 2 个元音字母。
|
示例 4:
1 2 3
| 输入:s = "rhythms", k = 4 输出:0 解释:字符串 s 中不含任何元音字母。
|
示例 5:
1 2
| 输入:s = "tryhard", k = 4 输出:1
|
提示:
1 <= s.length <= 10^5
s 由小写英文字母组成
1 <= k <= s.length
思路:
一开始想着用暴力法,结果就很自然的超时了。然后想了一下,觉得应该能用动态规划来做,首先dp[i]的含义是以i为结尾的k个字符的字符串的元音数目。所以需要先初始化dp[k - 1]。
从i == k开始遍历时,存在两种大情况(s[i - k]代表每次子字符串的首个字符):
- 若
s[i - k]为元音字母:
- 若
s[i]也为元音字母,则dp[i] = dp[i - 1]
- 若
s[i]不为元音字母,则dp[i] = dp[i - 1] - 1
- 若
s[i - k]不为元音字母:
- 若
s[i]为元音字母,则dp[i] = dp[i - 1] + 1
- 若
s[i]不为元音字母,则dp[i] = dp[i - 1]
然后每次存储最大值,最后返回即可。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| class Solution { public: bool judge(char c){ if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return true; return false; } int maxVowels(string s, int k) { vector<int> dp(s.length(), 0); for(int i = 0; i < k; i++){ if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') dp[k - 1]++; } int num = dp[k - 1]; for(int i = k; i < s.length(); i++){ if(judge(s[i - k])){ if(judge(s[i])) dp[i] = dp[i - 1]; else dp[i] = dp[i - 1] - 1; }else{ if(judge(s[i])) dp[i] = dp[i - 1] + 1; else dp[i] = dp[i - 1]; } if(dp[i] > num) num = dp[i]; } return num;
} };
|