长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0
刚开始看到这道题第一个想法肯定是去暴力,直接上两层循环,爆力就完事了。其实除此之外,还可以去采用一个更加巧妙的方法,俗称滑动窗口。千万别被名字吓到,其实就是循环再加条件控制循环,也是双指针。
从题目入手分析,因为正整数数组,sum越加越大,我们的基本思路是在一个循环中让其下标不断向前循环,当由前后指针组成的窗口,其和大于等于target时向前移动前指针,并对前指针改变后的窗口继续求和,判断其是否大于target,并记录窗口中元素个数。具体实现方法如下:
var minSubArrayLen = function(target, nums) {
var a=0;
var sum=0;
var b=0;
let res=Infinity;
let len=nums.length;
while(b<len){
sum+=nums[b];
while(sum>=target){
res=Math.min(res,b-a+1);
sum=sum-nums[a];
a++;
}
b++;
}
return res===Infinity ? 0 :res;
};
滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。
关于时间复杂度的计算其实我现在也很迷惑。