一、题目描述
再一个正整数数组nums中找到【总和】大于target的【长度最小】的连续子数组
【示例】
输入:target=12, nums={,4,6,2,4,9,8,7}
输出:2
二、解题思路
1.暴力解法:
用两层嵌套循环,外层循环确定开始位置,内层循环确定子数组终止位置
通过sum计数,判断是否大于target
时间复杂度为O(),空间复杂度为O(1)
对子数组的长度,显然可以通过以下公式求得:
length=j-i+1;
总体代码如下:
int Find(vector<int> nums, int target)
{
int size = nums.size();
int minima = 100000000;
int sum = 0;
for (int i = 0; i < size; i++)
{
int j = i;
while (j<size)
{
sum += nums[j];
if (sum >= target)
{
minima = min(minima, j - i + 1);
break;
}
j++;
}
sum = 0;
}
return minima != 100000000 ? minima : 0;
}
2.滑动窗口(重要)
滑动窗口法也类似于一种双指针法(快慢指针),因为要求两个指针之间所有数的和,所以更像一个窗口。
难点:起始指针和终止指针随窗口内数字和sum的变化关系
用两个循环来解决:
1.如果sum<target,则需要继续拓宽窗口,把end指针后移(代码中用j表示)
2.如果sum>target,则需要缩短窗口,把start指针后移(代码中用i表示)
注意:
所有对指针的移动,都应该同时修改sum和len的值,并在满足条件时修改【最小值res】
这样修改后,算法时间复杂度下降到O()
具体代码如下:
int window(int target, vector<int>nums)
{
int res = INT32_MAX;
int len = 0;
int sum = 0;
int i = 0;
for (int j = 0; j < nums.size(); j++)
{
sum += nums[j];
while (sum >= target)
{
len = j - i + 1;
res = min(len, res);
sum -= nums[i];
i++;
}
}
return res == INT32_MAX ? 0 : res;
}
三、LeetCode209
本题显然暴力解法的时间复杂度过高,在Leetcode上无法通过,但滑动窗口已经能达到不错的性能