【力扣刷题】【滑动窗口算法】长度最小的子数组

目录

题目

​编辑暴力算法

        优化


题目

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

暴力算法

用两个指针,两层循环,列举出所有的结果,把每次符合的最优结果更新到临时变量里。代码如下

class Solution {
public:
 int minSubArrayLen(int target, vector<int>& nums) {
 // 记录结果
int ret = INT_MAX;
 int n = nums.size();
 // 枚举出所有满⾜和⼤于等于 target 的⼦数组[start, end]
 // 由于是取到最⼩,因此枚举的过程中要尽量让数组的⻓度最⼩
 // 枚举开始位置
 for (int start = 0; start < n; start++)
 {
 int sum = 0; // 记录从这个位置开始的连续数组的和
 // 寻找结束位置
 for (int end = start; end < n; end++)
 {
 sum += nums[end]; // 将当前位置加上
 
 if (sum >= target) // 当这段区间内的和满⾜条件时
 {
 // 更新结果,start 开头的最短区间已经找到
 ret = min(ret, end - start + 1);
 break;
 }
 }
 }
 // 返回最后结果
 return ret == INT_MAX ? 0 : ret;
 }
};

        优化

        如何做优化呢?题目里说数组里的都是正整数,当区间里已经符合条件了,我们还需要把最右边的指针重置到左边吗

        上图中,灰色的区间已经是符合条件的区间了,此时黑色指针向右移动一格,如果是暴力算法,红色指针应该重置到黑色指针的位置,然后向右遍历。我们来讨论一下,红色指针有必要重置吗?显然没有必要的

        黑色指针向前移动一个之后此时会有两种情况

        1.灰色区间依旧符合条件,红色指针被重置然后遍历,依旧是当前的灰色区间。

        2.灰色区间不符合条件,红色指针被重置后遍历,由于整个区间都是正整数,灰色区间的大小只会增加。

        也就是说,我们完全没必要再让红色指针遍历一灰色区间了。

        那么灰色区间就是滑动窗口算法中的窗口,这道题的算法如下:

        1.红色指针右移,数据入窗口

         2.判断窗口是否符合条件

        3.不符合条件继续让新数据入窗口,符合条件更新最优结果,并且让最左边的数据出窗口

代码如下:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size();
        int sum = 0;
        int l_ptr = 0;
        int r_ptr = 0;
        int len = INT_MAX;

        while (r_ptr < n) {

            sum += nums[r_ptr++];
            while (sum >= target) {
                len = min(len, r_ptr - l_ptr + 1);
                sum -= nums[l_ptr++];
            }
        }
              
        return len == INT_MAX ? 0 : len - 1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值