【魅力算法】'长度最小的子数组' 双指针&滑动窗口实现 |刷题打卡

103 阅读1分钟

题目描述:

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

 

示例:

输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
 

进阶:
    
如果你已经完成了 O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

滑动窗口、双指针(left,i)

  • 定义指针left为窗口的起始下标;left=0;
    • 窗口从下标i=0开始滑动;
  • 遍历nums计算当前窗口的sum和;
    • 当前窗口即为当前连续子数组;
  • 如果sum>s;即当前窗口为满足条件的子数组时;
    • 记录当前窗口的最小子数组长度Math.min(i-left+1,min)
    • 并开始滑动窗口,left++;
  • 边界提前处理:
    • 当num.length==0时;return 0;
    • 当nums[0]>=s时;return 1;
  • 特殊情况:
    • 当不存在符合条件的子数组时;return 0;

image.png

代码

/**
 * @param {number} s
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(s, nums) {
    let len=nums.length,sum=0,min=len,left=0;
    if(len==0){
        return 0;
    }
    if(nums[0]>=s){
        return 1
    }
    for(let i=0;i<len;i++){
        sum+=nums[i];
        while(sum>=s){
            min=Math.min(i-left+1,min);
            sum=sum-nums[left];
            left++;
        }   
    }
    if(left==0&&sum<s){
        min=0;
        return min
    }
    return min;
};