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';
    }
原文地址:https://www.cnblogs.com/WakingShaw/p/13630762.html