已解答
中等
相关标签
相关企业
给定一个含有 n ****个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 ****target ****的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度 。 如果不存在符合条件的子数组,返回 0 。
示例 1:
输入: target = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入: target = 4, nums = [1,4,4]
输出: 1
示例 3:
输入: target = 11, nums = [1,1,1,1,1,1,1,1]
输出: 0
提示:
1 <= target <= 1091 <= nums.length <= 1051 <= nums[i] <= 104
进阶:
- 如果你已经实现 **`O(n)` 时间复杂度的解法, 请尝试设计一个 `O(n log(n))` 时间复杂度的解法。
题解: 1、想到了使用滑动窗口的思路,但是逻辑比暴力解法复杂,所以理了很久。 现在看其实就两个while,一个是left+,加到sum小于target停止;另一个是right+,加到sum大于target停止。 2、写两个循环时候的边界条件不好设定,特别是数组长度为1或者为0的特殊情况,因此后来选择在函数开始时先处理一些边界,后面的循环不用考虑那么复杂的情况了。这是一个可以沿用的方法,如果边界条件很特殊,可以在开头单独处理掉。
发生的bug:漏了更新sum的值。
int minSubArrayLen(int target, int* nums, int numsSize) {
if (numsSize == 0)
return 0;
if (nums[0] >= target)
{
return 1;
}
int left = 0, right = 1;
int sum = nums[0];
int lestlen = numsSize;
int flag = 0;
while (right <= numsSize - 1)
{
sum = sum + nums[right];
while (left <= right && sum >= target)
{
//记录下当前最小长度
flag = 1;
if (right - left + 1 < lestlen)
{
lestlen = right - left + 1;
}
//继续尝试缩小长度
sum = sum - nums[left];
left ++;
}
right ++;
}
if (flag == 1)
{
return lestlen;
}
else
return 0;
}