题目描述:
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
思路:
采用滑动窗口思想,定义一个指针j记录子数组的开始下标,用 i 遍历数组,定义sum记录下子数组的前缀和,再用minLen记录下子数组出现过最小的长度。只要sum大于目标值,sum减去子数组的开始下标的数值,sum往后加,j也往后走,由于在减去子数组的头数据时 i 一直不变,所以子数组长度可能出现一直减小的情况,这时min用来更新最小长度。
代码实现如下:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
if(nums.length == 0) return 0;
int sum = 0;//前缀和
int j = 0;//用来记录当前窗口开始的位置,即子数组的开始下标
int minLen = 0;//用来滑动过程中记录下出现过的最小子数组
for (int i = 0;i < nums.length;i++) {
sum += nums[i];//一直向后走就管
//只有前缀和大于目标值才能进入循环比较最小长度,不大于就是0,不用比较。
while (sum >= target) {
//判断如果是第一次进入循环就要用当前子数组长度替换掉0,不是第一次就用Math.min函数比较找出较小的长度记录下来。
minLen = minLen == 0 ? i - j + 1 : Math.min(minLen,i - j + 1);
//只要sum大于目标值就一直减掉头,加上后面的值。然后下标j++。
sum -= nums[j++];
}
}
return minLen;
}
}