**给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组
[numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。**
思路分析:
时间复杂度为O(n)的解法就是采用所谓的滑动窗口(双指针),通过不断改变子数组的起始位置和终止位置,逐渐得到>=target的最小的连续子数组的长度。
给定两个指针i,j分别指向起始位置(nums[0]),终止位置(j及之前元素之和大于等于target)
通过起始位置与终止位置移动控制窗口,当sum(sum为它们之间元素之和)>=target时去移动i,小于时去移动j,
窗口的结束位置就是相当于i或j遍历到数组尾。
1,滑动窗口:
//滑动窗口(双指针)
public static int minSubArrayLen2(int target, int[] nums) {
int result=1000001;//取数组最大长度
int sum=0;//子数组元素的和
int kidLength=0;
int i=0;//滑动窗口起始的位置
for(int j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=target){
kidLength=j-i+1;
result=result>kidLength?kidLength:result;//为了保证得到最小的连续子数组
sum-=nums[i++];
}
}
if(result==1000001){
return 0;
}else{
return result;
}
}
2,普通方法:
//超出时间限制
public static int minSubArrayLen1(int target, int[] nums) {
int length=0;
int sum=0;
for(int i=0;i<nums.length;i++) {
for(int j=0;j<nums.length-i;j++) {
int temp=j;
for(int k=0;k<=i;k++) {
sum+=nums[j++];
}
if(sum>=target) {
length=i+1;
return length;
}
j=temp;
sum=0;
}
}
return 0;
}