【算法专题】滑动窗口之209. 长度最小的子数组(力扣)

 欢迎来到 CILMY23 的博客

🏆本篇主题为:滑动窗口之209. 长度最小的子数组(力扣)

🏆个人主页:CILMY23-CSDN博客

🏆系列专栏:Python | C++ | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算法专题 | 代码训练营

🏆感谢观看,支持的可以给个一键三连,点赞收藏+评论。如果你觉得有帮助,还可以点点关注


 题目:

209. 长度最小的子数组 - 力扣(LeetCode)

给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

题目解析:

通过题目就可以发现以下信息 

  1. 找到长度最小的子数组
  2. 子数组求和和target值相同
  3. 数组和target都是正整数
  4. 代码返回子数组长度
  5. 如果不存在符合条件的子数组,返回 0 

算法原理: 

这题我们用一个高大上的双指针算法 --- "同向双指针(滑动窗口)"

滑动窗口理解起来就像是双指针算法的另外一种用法,有个高大上的名字“同向双指针”。

滑动窗口:

假设有一个数组nums,现在我们用一个框框括起来,我们把这个框框叫做窗口

现在有一个target,要让我们求窗口数之中的和,假设窗口的左边是left,窗口的右边是right,窗口的长度是len = 3,我们求了一个sum表示窗口中的和,因为sum = 6 < target = 7,所以我们可以理解为窗口中的数不够多,这时候窗口就要扩大,也就是right就要加1.

right 向前移动后,我们要再计算sum的值,sum此刻等于8,比target大了,那我们就要缩小这个窗口了,此时不可能让right 缩小,因为right所负责的这个边界是让数组的值进入的,所以要让left++,这个nums数组中的数值 2 就“出窗口了”。当时在出窗口前我们要做到一点,更新结果,更新结果有的时候会在进窗口更新,有的时候是在出窗口前更新,随机应变。那这道题刚好是在判断满足的时候,更新结果,所以更新结果这一步骤不急着去做。

重复之后,我们就可以找到len为2的情况了。 

滑动窗口步骤:

1.初始化left和right指针,left = 0,right = 0

2.进窗口

3.判断

出窗口

4.出窗口继续判断

其中2,3步是一直循环的。

更新结果有的时候会在进窗口更新,有的时候是在出窗口前更新,随机应变。

什么时候用?

利用单调性,发现两个指针都可以不回退,都只在同一个方向上移动,这时候就用滑动窗口。

本质是什么?

本质是一个同向双指针

时间复杂度(不要看循环,分析复杂度)

时间复杂度为O(n),最差情况就是right指针和left指针都走完了数组

代码解析:

注意的点:

len 一开始设置成max的最大值,防止每次传出去的值是0

在返回的时候判断一下len的值,因为有可能存在不符合条件的子数组,需要返回 0 

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums)
    {
        int left = 0;
        int right = 0;
        int len = INT_MAX;
        int sum = 0;
        for(left = 0,right = 0;right < nums.size();right++)
        {
            sum += nums[right]; //进窗口
            while(sum >= target) //判断
            {
                len = min(len,right - left +1); //更新结果
                sum -= nums[left]; //出窗口
                left++;
            }
        }
        return len == INT_MAX ? 0 : len;
    }
};

🛎️感谢各位同伴的支持,本期算法专题就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞,收藏+评论,可以的话还希望点点关注,若有不足,欢迎各位在评论区讨论。    

  • 12
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值