力扣 第209题 长度最小的子数组 (不定长滑动窗口)

        不定长滑动窗口:让元素先进窗口,然后根据条件判断是否需要缩小窗口长度(窗口左端点右移,右端点不动),来求解问题。不定长滑动窗口最主要的是找到缩小窗口的临界条件。解题方式基本与定长滑动窗口解题思路一致。

解题思路:

          以此题为例,题目要求找出数组中满足其总和大于等于 target 的长度最小的子数组,建立滑动窗口,窗口内的元素就是一个子数组,当窗口右端点到达某一个值时,窗口内元素总和减去窗口左端点的值仍然大于等于目标值 targe  时,因为数组是正整数的数组,如果窗口右端点继续往右走,那后续肯定都大于目标值 targe ,而我们要找的是长度最小的子数组,所以此时窗口右端点没有必要往右走,应该让窗口左端点往右走,以此来缩小窗口长度,同时保证窗口中元素和都大于等于目标值targe,直到找到满足需求的最小子数组的长度,再更新信息,然后继续控制窗口往右移,直至遍历完数组就找了数组中满足其总和大于等于 target 的长度最小的子数组。

将上述思想转化为代码:

  1. 定义变量:sum记录窗口中的元素累加和;left记录窗口左端点;循环遍量right记录窗口右端点;min来记录窗口长度,即子数组的长度;min赋一个极大值:Integer.MAX_VALUE。
  2. 遍历数组,建立窗口。for循环遍历,循环条件为窗口右端点是否到达数组最右边,即right < nums.length ,然后通过 进窗口-->判断是否需要缩小窗口长度(出窗口)-->更新信息 来求解。
  3. 进窗口:当元素进入窗口时,我们要记录当前窗口中的元素累加和,即sum+=nums[right]。
  4. 判断是否需要缩小窗口长度:当窗口中的元素累加和sum减去窗口左端点的值num[left]仍然大于等于目标值targe时,缩小窗口长度,因为不知道窗口需要缩小几次,所以用while。缩小窗口前先让 sum-=num[left] ,再让eft++即可。判断是否需要缩小窗口的条件为 sum-nums[left] >= targe 。因为不知道窗口需要缩小几次,所以用while循环。
  5. 更新信息:更新信息前我们应判断 sum>= targe,true再更新信息。min取min和满足条件的当前窗口的长度两个的较小值即可,注意此窗口的长度为 right-left+1 ,要加1是因为当right和left指向同一个元素时,窗口长度为1而不是0;
public static int minSubArrayLen(int target, int[] nums) {
    int min = Integer.MAX_VALUE;
    int sum = 0;
    int left = 0;
    for(int right = 0; right < nums.length; right++){
        // 进窗口
        sum += nums[right];
        // 判断是否需要缩小窗口长度
        while(sum - nums[left] >= target){
            sum -= nums[left];
            left++;
        }
        // 更新信息
        if (sum >= target) {
            min = Math.min(min, right - left + 1);
        }
    }
    return sum>=target?min:0;
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值