本文参考卡哥的代码随想录,加上了一点自己的理解,感谢Carl的分享。
代码随想录
视频讲解
一. 题目
力扣209题
给定一个含有 n 个正整数的数组和一个正整数 target ,找出该数组中满足其和 ≥ target 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
提示:
1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5
二. 解题思路
1.暴力解法
使用两个指针,第一个指针nums[i]用来遍历数组。nums[i]指向数组的第一个元素后,第二个指针nums[j]依次指向后面的元素,目的是将第一个元素与后面的元素依次相加,直到判断出__nums[i]与nums[j]所指区间的所有元素和__>=target时,记录元素个数result,此时的result一定为以 nums[i]指向的元素 为起点满足元素和>=target的最少个数。然后,将nums[i]后移一位,判断以第二个元素为起点满足条件的数组中元素个数,若是小于先前的result则进行替换。以此类推,直到指针nums[i]遍历完整个数组。
代码思路:
(result:目标数组长度;i:第一个数组指针下标;j:第二个数组指针下标;subLength:i,j 之间数组长度;sum:i,j 之间数组元素之和 )
- 初始化result为最大整数(INT32_MAX),以便后期可以作比较。
- 写第一个for循环用来遍历数组,且每次指针后移的时候,sum 清零。
- for循环嵌套里第二个for循环(j = i,为起点),取所有和。
- 如果达到期待值,计算数组长度,result值更新为最小长度。跳出第二个循环。
- 最后返回result,若没有符合条件的数组,则返回0。
2.滑动窗口
同样使用两个指针,初始化两个指针nums[i], nums[j]均指向数组的首元素。不同之处在于我们用靠右的指针nums[j]来遍历数组。随着nums[j]的右移,依次相加各元素,记和为sum。当sum达到条件时进入循环,元素和sum减去nums[i]的值,数组指针nums[i]右移。继续判断sum是否满足条件,不断右移i,减掉nums[i]的值,直到sum<target,此时i,j范围内的数组为以nums[j]为尾端满足条件的最短数组。一次循环结束。将 j 右移,继续下次的循环判断。
代码思路:
- 初始化result为最大整数(INT32_MAX),以便后期可以作比较。
- 写第一个for循环( j )用来遍历数组。j右移的同时依次相加元素,记和为sum。
- 当sum>=target时,进入循环。计算数组长度subLength = j - i + 1比较并更新result。sum = sum-num[i] ,右移i。直到sum不满足条件,跳出while循环,进入for循环,判断下一个以num[j]为末端的满足条件的数组。
- 最后返回result,若没有符合条件的数组,则返回0。
三. 代码
暴力解法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX; //将result设为最大值,以便后面比较
int sum = 0;
int subLength = 0;
for ( int i = 0; i < nums.size(); i++) {
sum = 0;
for ( int j = i; j < nums.size(); j++) {
sum += nums[j]; //计算数组和
if ( sum >= target) {
subLength = j - i + 1; //计算数组长度
result = result < subLength ? result : subLength; //选择最小长度
break;
}
}
}
return result == INT32_MAX ? 0 : result; //没有期待数组则返回0
}
};
滑动窗口解法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX; //将result设为最大值,以便后面比较
int sum = 0;
int i = 0;
int subLength = 0;
for( int j = 0; j <nums.size(); j++) {
sum += nums[j];
while (sum >= target) {
subLength = j - i + 1;
result = result < subLength ? result : subLength;
sum -= nums[i];
i++;
}
}
return result == INT32_MAX ? 0 : result;
}
};