题目
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
关键点
- 用滑动窗口的思想,左右两个指针滑动,刚开始两个指针都放在最前面,然后右指针往右划,划到满足数组和sum>=target为止,此时记录一次最小长度。
- 当记录一次最小长度以后,左指针也往右滑,左指针每右划一位,则数组和sum减去左指针的值,直到数组和sum<target,则又回到了上面关键点1的循环(右指针往右移)
- 大循环的条件是左指针追右指针,而数组和与target比大小只是用来判断左右指针的移动
- 初始的目标长度应该是一个很大的数,这样结果满足小于很大的数才能执行下去
,否则设为0根本执行不了,而且要用INT32_MAX表示最大的数。注意当没答案时才返回0,而不是一开始就把目标长度设为0!
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left = -1, right = -1,len = INT32_MAX, sum = 0; //目标长度len设最大的数
while(left <= right){ //注意要<= ,否则会出错,因为最终left是可以追上right,并且最开始的left和right都设为-1相等,所以这里要<=才能第一次进来判断
if(sum < target){
right++; //在这里右指针先移一位,下面的sum才能加
if(right >= nums.size())
break;
sum += nums[right];
}
else{
if(right - left < len){ //判断后才能更新,设len最大是因为第一次要进来
len = right - left;
}
left++; //左指针先移一位,下面的sum才能减
if(left > right) //上面left++,这里要判断是否成立,虽然看起来有点多余,毕竟都在while里定义了条件
break;
sum -= nums[left]; //做指针右移,数组和sum要减去失去的左区间
}
}
return len == INT32_MAX ? 0: len; //注意当len为初始值没变的时候才返回0,而不是初始值设为0
}
};