Leetcode 1456. Maximum Number of Vowels in a Substring of Given Length

问题理解

给定一个字符串 s 和一个整数 k,要求找出 长度恰好为 k 的连续子串中,包含最多元音字母(a, e, i, o, u,不区分大小写)的个数

  • 元音字母:a, e, i, o, u(含大小写)
  • 子串必须 连续且长度严格等于 k
  • 目标:返回所有满足条件的子串中,元音数量的最大值

示例:输入:s = "leetcode"k = 3输出:2(子串 "lee" 或 "ode" 含 2 个元音)

解题思路:滑动窗口(Sliding Window)

由于子串长度固定为 k,非常适合使用 固定大小的滑动窗口

  1. 初始化:计算第一个窗口 [0, k-1] 中的元音数量。
  2. 滑动:窗口每次右移一位:
    • 移出左边字符(索引 i - k
    • 移入右边字符(索引 i
    • 根据这两个字符是否为元音,动态更新当前窗口的元音计数
  3. 记录最大值:每一步更新全局最大元音数。

时间复杂度:O(n)空间复杂度:O(1)

Trick

  1. 错误写法(常见陷阱):

    if(vowels.find(c)){...}// 危险!
    
    • string::find() 返回 索引(找到时 ≥0,未找到时为 string::npos
    • 当字符是 'a' 时,find 返回 0 → if(0) 为 false → 漏判元音
    • 当字符不是元音时,find 返回 npos(一个很大的无符号数)→ if(npos) 为 true → 误判为元音

    结果:只有 'a' 被当成非元音,其他所有字符(包括辅音)都被当成元音!

  2. 正确判断方式:

    // 方法1:显式比较
    bool isVowel(char c){
    return vowels.find(c)!= string::npos;
    }
    
    // 方法2:直接枚举(更高效、清晰)
    bool isVowel(char c){
    return c=='a'|| c=='e'|| c=='i'|| c=='o'|| c=='u'||
               c=='A'|| c=='E'|| c=='I'|| c=='O'|| c=='U';
    }
    
  3. 滑动窗口更新逻辑:

    cpp

    编辑

    // 窗口从 [i-k, i-1] 移动到 [i-k+1, i]
    if(isVowel(s[i]) && !isVowel(s[i - k])) curr++;// 新加入的是元音, 且移出的不是元音
    if(!isVowel(s[i]) && isVowel(s[i - k])) curr--;// 被移出的是元音,且新加入的不是元音
    

    注意:两个判断 独立进行,不能用 else if!

Code

class Solution {
public:
    int maxVowels(string s, int k) {
        int max = 0, curr = 0;
        int i = 0;
        while(i < s.length())
        {
            if(i < k) {
                if(is_vowel(s[i])) curr++;
            }
            else {
                if(is_vowel(s[i]) && !is_vowel(s[i-k])) curr++;
                if(!is_vowel(s[i]) && is_vowel(s[i-k])) curr--;
            }
            if(curr > max) max = curr;
            i++;
        }
        return max;
    }
    bool is_vowel(char c){
        string vowel = "aeiouAEIOU";
        if(vowel.find(c) != string::npos){
            return 1;
        }
        return 0;
    }
};
posted @ 2026-01-23 13:39  West11  阅读(2)  评论(0)    收藏  举报