解决定长滑动窗口问题

如果还不了解滑动窗口是什么的话可以先去百度或者leetcode上了解一下滑动窗口。该篇文章主要讲解固定长度的滑动窗口问题。相信我,学会该套路解决所有定长滑动窗口问题!!!话不多说,正题开始!在此先奉上定长滑动窗口的leetcode题单。注:该题单来自灵神,一位算法讲师,大家想要开始算法入门学习可以关注他的b站或leetcode账号。

分享丨【题单】滑动窗口与双指针(定长/不定长/至多/至少/恰好/单序列/双序列/三指针) - 力扣(LeetCode)


定长滑动窗口的一般套路:

定长滑动窗口的套路主要分为三步:

1. 入窗口

2.更新答案

3.出窗口


定长滑动窗口的代码模板:

  int main() {
       //固定长度为k的滑动窗口
       //定义最终答案和窗口内需要维护的变量
        int ans = 0;
        //left为窗口左边界,right为窗口的右边界
        for(int left = 0,right = 0;right<n;right++){
            //入窗口,更新维护信息
            //先形成长度为k的窗口 right到达k-1的时候说明第一个长度为k的窗口就形成了
            if(right < k-1) continue;
            //形成窗口后更新答案,一般求最大或者最小值,根据题目要求更新答案

            //出窗口
            //因为此时窗口的长度已经为k,下一次循环right++窗口的长度会变大,
            // 所以需要先将窗口左边界右移一次
            //注意左边界右移之后,窗口内维护的信息可能发现变化,需要更新窗口内信息
        }
        //最终返回答案
        return ans;
    }

定长滑动窗口例题:


下面让我们用这个套路看两个比较简单的定长滑动窗口的问题

题目链接:1456. 定长子串中元音的最大数目 - 力扣(LeetCode)

读题知道,该题让我们求长度为k的子字符串中包含最多的元音字母的个数。所以我们可以维护一个长度固定为k的窗口,用count记录窗口内元音字母的个数。下面让我们用上边的模板解决该题

class Solution {
public:
    int maxVowels(string s, int k) {
        int ans = 0;//最终答案
        int count = 0;//记录窗口内元音字母的个数
        //长度为k的滑动窗口
        for(int left = 0,right = 0; right<s.length();right++)
        {
            //1.入窗口
            //根据入窗口的字符是否是元音字母更新count
            if(s[right] == 'a' || s[right] == 'e' || s[right] == 'i' || s[right] == 'o' || s[right] == 'u')
                count++;
            //先形成第一个长度为k的窗口
            if(right < k - 1) continue;
            //2.更新答案
            ans = max(ans,count); 
            //3. 出窗口
            char out = s[left];//记录左边界要出窗口的字符
            //左边界字母是元音字母的话更新窗口内元音字母的个数即count--
            if(out == 'a' || out == 'e' || out == 'i' || out == 'o' || out == 'u')
                count--;
            left++;//左边界右移一格
        }
        return ans;
    }
};

是不是套用上面的模板解决此题就是轻而易举啊,那我们下边再看一道题

643. 子数组最大平均数 I - 力扣(LeetCode)

这道题让我们找出平均数最大且 长度为 k 的连续子数组,并输出该最大平均数。题目中长度为k的连续子数组提示我们应用滑动窗口去解决。那么我们套用定长滑动窗口的模板解决该题。

class Solution {
public:
    double findMaxAverage(vector<int>& nums, int k) {
        //定长滑动窗口
        double sum = 0.0;//窗口内维护k个数的和
        double ret = INT_MIN;//定义一个特别小的数,方便取最大值
        for(int left = 0,right = 0;right<nums.size();right++)
        {
            //1.入窗口
            sum += nums[right];
            //形成第一个窗口
            if(right < k - 1) continue;
            //2.更新答案
            ret = max(ret,sum / k);
            //3.出窗口
            sum -= nums[left];
            left++;
            //sum -= nums[left++];上边两行代码可以简写成这一行
        }
        return ret;//返回答案
    }
};

值得一提的是本题的出窗口操作,右边界入窗口的时候将sum += nums[right] 左边界出窗口的时候sum -= nums[left],因为加法减法互为逆运算,一加一减正好可以作为更新窗口内维护信息的两个操作,同理乘除亦可!


通过以上两道题目,相信大家已经对滑动窗口有了初步的了解。大家可以去开篇中的链接去刷其他的定长滑动窗口的题目了,后续我会更新题目的解法,最后希望大家多多关注,让我们共同提高,共同进步!

滑动窗口算法是一种用于决一些查找满足一定条件的连续区间的性质的问题的思想或技巧。它可以将双层嵌套的循环问题转换为单层遍历的循环问题,从而降低时间复杂度。滑动窗口算法的步骤通常包括维护两个指针left和right,表示当前窗口的左右边界。通过移动右指针扩大窗口,直到窗口内的元素之和满足某个条件。然后,移动左指针缩小窗口,直到不能再缩小为止。在这个过程中,记录窗口的最小度,并更新最小度的值。最后返回最小度。滑动窗口算法的优点包括时间复杂度较低、空间复杂度较低、简单易懂。然而,滑动窗口算法也有一些缺点,包括无法决所有子串问题、可能存在重复计算和可能存在局限性。总的来说,滑动窗口算法是一种有效的决特定类型问题的方法。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [滑动窗口算法精讲(Sliding Window Algorithm)](https://blog.csdn.net/qq_39559641/article/details/122793321)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [滑动窗口算法](https://blog.csdn.net/m0_63951142/article/details/130671127)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值