定一个含有 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
首先分析题目,如果这题不要求时间复杂度显而易见是一道非常简单的题目,只需要两个for循环就可以解出答案,但这并不是题目所考察的要点。
要想从O(n^2)降到O(n),对数组的方法通常有二分法,双指针法。
二分法在这里不符合要求,所以就想到双指针法,使用两个指针,右指针不断向右边移动,每移动一次就加到sum中,直到sum符合要求>=target,然后移动左指针直到sum<target,其中每移动都更新答案状态,重复以上步骤就得出答案,这个方法也叫滑动窗口法,本质上依然是双指针。
代码如下:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int l = 0;//左指针
int r = 0;//右指针
int sum = 0;
int ans = Integer.MAX_VALUE;//要求的是最小值,所以初始化为最大值
while(r <= nums.length - 1){
sum += nums[r];
r++;
while(sum>=target){ //每次符合要求的都要更新一次答案再减
int tmp = r - l;
ans = tmp < ans ? tmp : ans;
sum -= nums[l];
l++;
}
}
if(ans==Integer.MAX_VALUE)
return 0;
return ans;
}
}
如果有什么问题欢迎交流。