题目
分析
一般遇到这种题目最常见的做法就是暴力求解,即两层for循环,但是这样会导致时间复杂度来到O(n^2)。这里我们使用一种新的思想,即滑动窗口的思想:
其中左指针i代表窗口的起始位置,右指针j代表窗口的终止位置,首先i指针在数组下标为0的位置,然后j指针向右移动,并将经过的每一个元素相加,并将这些相加之后的值与要求的数进行比较,如果大于了进行比较的数target,那么就需要对左边指针所指的数进行判断,如果减去左边的数还是比target大的话,那么就需要继续减去左边的数,直到sum(这些所相加的值小于target为止)。这里不得不吐槽一句,说是滑动窗口,其实感觉更像是毛毛虫,因为先是左边的指针不动,右边的指针动,然后右边的指针不动,左边的指针动。
代码
int minSubArrayLen(int target, int* nums, int numsSize) {
int sum=0,i=0,j=0,len=numsSize,flag=0;
for(;j<numsSize;j++)
{
sum=sum+nums[j];
while(sum>=target)
{
flag=1;
if(len>(j-i+1))
{
len=j-i+1;
}
sum=sum-nums[i];
i++;
}
}
if(flag)
{
return len;
}
return 0;
}
官方代码
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int n = nums.size();
if (n == 0) {
return 0;
}
int ans = INT_MAX;
for (int i = 0; i < n; i++) {
int sum = 0;
for (int j = i; j < n; j++) {
sum += nums[j];
if (sum >= s) {
ans = min(ans, j - i + 1);
break;
}
}
}
return ans == INT_MAX ? 0 : ans;
}
};