目录
滑动窗口思想
滑动窗口,实际上是基于双指针的一种思想,有前后两个指针来控制窗口的大小。滑动窗口可分为两类,一类是静态窗口,一类是动态窗口。
如图所示这就是一个滑动窗口,j为滑动窗口的终止位置,i为滑动窗口的起始位置,两者根据题目的不同条件进行相应的变化 。
最小子数组
题目描述
给定一个含有 n
个正整数的数组和一个正整数 target
。找出该数组中满足其和 ≥ target
的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
示例1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3]
是该条件下的长度最小的子数组。
思路
这个题最简单的办法就是两层for循环遍历来实现,但是这个存在超时的情况,所以我们使用滑动窗口来实现。
- 如上图,j是作为窗口的终止位置的,i是作为窗口的起始位置,sum接收子数组和,并且再定义一个result接收子数组长度,
- 首先我们遍历数组,也就是窗口开始执行,j++,这时也就形成了窗口,此时sum的值也发生变化,判断sum和目标和target的大小,如果小于target,说明此时不满足,窗口继续扩大.
- 如果sum >= target ,此时说明满足题意其中之一,我们记录此时的长度result,但是需要求最小,所以从左边开始窗口减小,看是否还能满足题意,i++,同时sum-i的值。
- 只要满足sum>=target,都缩小窗口,然后result取最小值即可
代码实现
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i = 0; //起始指针
int sum = 0; //窗口和
int result = Integer.MAX_VALUE; // 窗口长度,由于要去最小值,所以定义为最大值
for(int j = 0; j < nums.length; j++){
sum += nums[j];
while(sum >= target){
result = Math.min(result,j - i + 1);
sum -= nums[i];
i++;
}
}
return result == Integer.MAX_VALUE?0:result;
}
}