关于滑动窗口算法的边界问题--LeetCode209

1.题目描述

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

2.代码

    //滑动窗口
    // 2, 7, 1, 2, 1, 3
    public static int minSubArrayLen1(int target, int[] nums) {
        int n = nums.length;
        if (n == 0) {
            return 0;
        }
        int minL = Integer.MAX_VALUE;
        int L = 0, R = 0; //滑动窗口的左右边界
        int sum = 0;

        while ( R < n ) {
            sum += nums[R];
            while ( sum >= target ) {
                minL = Math.min(minL, R - L + 1);
                sum -= nums[L];
                L++;
            }
            R++;
        }
         return minL == Integer.MIN_VALUE ? 0 : minL;

    }

3.相关论述

核心思想

" 涉及连续子数组的问题,我们通常有两种思路:一是滑动窗口、二是前缀和。"
本题滑动窗口的核心思想是:遍历一次数组,来找到以每个元素为首的连续子数组中最小的子数组长

什么时候结束程序的循环?

窗口的左边界在sum值大于等于target值时,才进行右移。但是这其中存在一个边界问题:什么时候结束外循环。
我们不妨这么想:右边界始终是比左边界更早到达数组的末尾(下标 = n-1),因此我们以窗口的右边界跳出数组边界作为结束外循环的条件。但这时候,我们又会想窗口右边界到达数组末尾(此时还没有跳出数组),如果窗口左边界并没有遍历到数组末尾,我们怎么找到在这之后的每次窗口中存在的满足大于等于target的子数组呢?。此时,剩下的子数组是左边界到数组末尾(下标 = n-1)的元素组成的,左边界是从左往右移动的,由于数组元素都是正整数,只要有一次窗口内的sum值小于target,我们就没必要在继续移动左边界了,直接跳出内循环,让最后的右边界自增,最后结束外循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值