题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
eg:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3]
是该条件下的长度最小的子数组。
分析:
当时看到这道题,我第一个想法就是利用双层for循化,外层循环遍历区间的开始指针,内层循环遍历区间的末尾指针.
代码:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum = 0;//区间所有数的和
int ans = Integer.MAX_VALUE;
for(int i =0; i<nums.length;i++){//开始指针
sum = 0;
for(int j=i; j<nums.length; j++){//末尾指针
sum +=nums[j];
if(sum >= target){
ans = Math.min(ans, j-i+1);
break;
}
}
}
return ans==Integer.MAX_VALUE?0:ans;
}
}
但很遗憾,超出时间限制
滑动窗口了解一下.
利用一层for循环替代暴力解法中的双层for循环.
这一层for循环中的指针j代表的是区间的末尾指针,区间初始指针用一个常数i标识(初始为0),明白什么时候移动初始指针非常重要
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int j = 0;//末尾指针
int i =0;//开始指针
int sum = 0;//开始指针到末尾指针之间的数组和
int ans = Integer.MAX_VALUE;
for(;j<nums.length;j++){
sum += nums[j];
while(sum>=target){//此时是初始指针i,满足sum>=target条件时,j最小的时候,即区间长度(j-i+1)最小的时候
ans = Math.min(ans, j-i+1);
//.开始指针向后移动
sum -=nums[i];
i++;//所以此时可以移动初始指针
}
}
return ans== Integer.MAX_VALUE? 0:ans;
}
}