leetcode -- 209 长度最小的子数组[滑动窗口/c++]

原题链接:209. 长度最小的子数组 - 力扣(LeetCode)

算法原理:

滑动窗口其实就是同向双指针,因为计算结果的单调性,在符合条件的情况下,左右指针不必往回回溯,而实现优化的效果。

滑动窗口分为4步(构成一个循环)

1. 进窗口(对right指针指向的数据进行处理)

2.判断(判断的作用是决定是否要进行出窗口操作)

3.出窗口(一般是移动left指针)

4.更新状态(可能在出窗口前,也可能在出窗口后,依情况而定)

这里的进出窗口针对的是数组中的元素,比如right++后指向的元素,就表示被放进了窗口。

为什么滑动窗口不会漏解?

理由一开始就说了,根据计算结果的单调性,省略掉的结果不影响最终值。

比如此题中,滑动窗口(双指针包围的数)内的数值和已经大于或等于目标值,此时right再++的话,len长度就更长了,题目要求返回长度最小的子数组长度,所以没有再让right++的必要,直接让left++,开始遍历下一个子数组。

注意,left++时,right不必重新回到left位置,只要让sum减去原本的left指向的值即可。因为我们是在一达到题目要求(大于等于目标值)的情况下就进行调整的,也就是出窗口操作,所以也不可能存在漏解的情况。

代码

此题更新状态需要用到left和right指针的相对位置,所以是在出窗口之前更新状态

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值