一、209.长度最小的子数组
给定一个含有 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 <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
进阶:
- 如果你已经实现
O(n)
时间复杂度的解法, 请尝试设计一个O(n log(n))
时间复杂度的解法。
代码随想录提供的O(n)
时间复杂度的解法,是滑动窗口的解法:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0;
// 考虑有多个符合情况的子数组,为了后续找到最小的长度子数组
int result = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
/**
* +1的原因: 加入目标数是5,数组是[2,3,1,2,4,3]
* 那么2+3就等于5,此时left=0,right=1,但是实际要输出的是长度2,而不是两者的差值
*/
result = Math.min(result, right - left + 1);
sum -= nums[left++];
// 上一行代码与下列代码作用相同
// sum -= nums[left];
// left++;
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
leetcode上的大佬就是多啊,不理解这个方法的小伙伴可以看看下面这段话,解释的很形象,哈哈哈
可以理解为左右指针中间窗口的sum为两指针的“共同财产”,就是右指针一直在努力工作挣钱,好不容易共同财产大过target,记录一下两指针之间的距离,结果左指针就开始得瑟挥霍,不停花钱(往右移动),结果花钱一直花到sum又小过target,此时右指针不得不再次出来工作,不停向右移动,周而复始,最后取左右指针离得最近的时候