1456. 定长子串中元音的最大数目(原始暴力匹配法以及滑动窗口法)

1.暴力求解

class Solution {

public:
    int maxVowels(string s, int k) {
        int maxVowels = 0;
        for(int i = 0;i<s.size();i++){
            if(i+k > s.size())  return maxVowels;
            string cur_str = s.substr(i,k);
            maxVowels = max(countVowel(cur_str),maxVowels);
        }
        return maxVowels;
    }
    int countVowel(string str){
        int vowel_num = 0;
        for(int i = 0;i < str.size();i++){
            switch(str[i]){
                case 'a':
                case 'e':
                case 'i':
                case 'o':
                case 'u':
                    vowel_num +=1;
            }
        }
        return vowel_num;
    }
};

最后求解后时间复杂度为:
O ( k ⋅ n ) O(k·n) O(kn)

2.采用滑动窗口方法

class Solution {

public:
    int maxVowels(string s, int k) {
        int cur_vowel = 0;
   
        for(int i =0;i < k;i++){
            cur_vowel += isVowel(s[i]);
        }
        int res = cur_vowel;
        for(int i = k;i<s.size();i++){
            cur_vowel += isVowel(s[i]) - isVowel(s[i-k]);
            res = max(cur_vowel,res);
        }
        return res;
    }
    bool isVowel(char& c){
        return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    }
};

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

 cur_vowel += isVowel(s[i]) - isVowel(s[i-k]);

这一步的含义是:
向右滑动一格后(即i++后),考虑s[i](表示移进来的一格),s[i-k](移出的一格),可分为以下情况:

  1. 如果s[i] == 1(即s[i] 为元音),s[i-k]也为元音,则 元音增加数目为0
  2. 如果s[i] == 1,s[i-k] == 0,即移进来元音,移出去非元音,则数目+1
  3. 如果s[i] == 0,s[i-k] == 1 ,即移进来非元音,移出去元音,则数目-1
  4. 如果s[i] == 0,s[i-k] == 0,即移进来非元音,移出去非元音,则数目不变

综上,可概括为上式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
滑动窗口(Sliding Window)是一种常见的数组或字符问题的解决方。它通常用于在给数组或字符寻找一些连续的区间,这些区间需要满足一的条件。滑动窗口的基本思想是维护一个窗口,通过调整窗口的起始位置和结束位置来寻找符合条件的区间。 下面是一个使用滑动窗口解决字符问题的例子,该问题是要找到一个字符最短的包含所有指字符的子。 ```python def min_window(s: str, t: str) -> str: # 初始化字典 needs = {} for c in t: needs[c] = needs.get(c, 0) + 1 # 初始化窗口和计数器 left, right, cnt = 0, 0, len(t) # 初始化最小覆盖子的起始位置和长度 start, length = 0, float('inf') while right < len(s): # 如果当前字符在需要的字符,计数器减一 if s[right] in needs: needs[s[right]] -= 1 if needs[s[right]] >= 0: cnt -= 1 right += 1 # 如果计数器为0,则找到了一个符合要求的子 while cnt == 0: # 更新最小覆盖子的起始位置和长度 if right - left < length: start = left length = right - left # 如果当前字符在需要的字符,计数器加一 if s[left] in needs: needs[s[left]] += 1 if needs[s[left]] > 0: cnt += 1 left += 1 return '' if length == float('inf') else s[start:start + length] ``` 在这个例子,我们首先初始化了一个字典 `needs`,用于存储需要的字符及其出现次数。然后,我们初始化了窗口的起始位置和结束位置为0,并将计数器 `cnt` 初始化为需要的字符的总数。接下来,我们开始移动右指针 `right`,并在遍历字符的过程不断更新字典 `needs` 和计数器 `cnt`,直到找到一个符合要求的区间。一旦找到符合要求的区间,我们开始移动左指针 `left`,直到不能满足条件为止。在移动左指针的过程,我们不断更新最小覆盖子的起始位置和长度。最后,我们返回最小覆盖子,如果不存在符合要求的子,则返回空字符
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值