长度最小的子数组

给定一个含有 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)。

关于时间复杂度的计算其实我现在也很迷惑。