Maximum Number of Vowels in a Substring of Given Length
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, u).
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
求定长字符串中元音字母的最大个数,很明显,直接的思路就是,每个子字符串中都去计算元音字母的个数,然后取其最大值,即可求得其解:
public int maxVowels(String s, int k) { if(s == null || s.length() == 0) return 0; int res = 0; for(int i = 0; i <= s.length()- k ; i++) { String str = s.substring(i, i+k); int len = count(str); res = res > len ? res : len; } return res; } public static int count(String str) { int len = 0; for(int i = 0; i < str.length(); i++) { if(str.charAt(i) == 'a' || str.charAt(i) == 'e' || str.charAt(i) == 'i' || str.charAt(i) == 'o' || str.charAt(i) == 'u') { len++; } } return len; }
然而,这种方法够简单直白,但是不够效率。个人测试了一下,最终是超时的(102/106)。因此,这种方法算不上好的解法。
可以分析一下,每个子字符串中都求一遍,我们可以发现,前后两个子字符串中,有k-1个字符是重复的,而一共计算的子字符串是length-k+1,那么我们重复计算的字符的数目就很大了。因此我们可以改进一下:
重复的字符,我们在计算上一个子字符串的时候,是已经做了处理的,因此在处理下一个子字符串,我们可以保留上次的结果,而只处理字符串的边界,即首部和尾部
=====>
双指针法(就这里而言,滑动窗口可能更为贴切)就可以很明显的出现在脑海中了:
设置左右指针,右指针首先滑动,并且在滑动的过程中,统计出现的元音字母的个数,当窗口的宽度到达k时,是我们处理的重点:此时开始,左右指针一起滑动,步长都为1,并且在滑动的过程中,如果右指针所指向的字符为原因字母,个数+1,左指针所指向的字符为元音字母,个数-1,并且在每一次的滑动中,都及时更新结果集。
代码实现如下:
public int maxVowels(String s, int k) { if(s == null || s.length() == 0) return 0; int res = 0, left = 0, count = 0; for(int right = 0; right < s.length(); right++) { char ch = s.charAt(right); if(right < k) { if(isVowel(ch) ) { count++; } res = count; }else { if(isVowel(ch) ) { count++; } char c = s.charAt(left); if(isVowel(c) ) { count--; } res = res > count ? res :count; left++; } } return res; } public static boolean isVowel(char ch) { return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'; }