[路飞]_leetcode_剑指 Offer II 008. 和大于等于 target 的最短子数组

121 阅读2分钟

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

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

示例 2:

输入:target = 4, nums = [1,4,4]
输出:1

示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

解题思路

设置左右指针,移动右指针,当左右指针指向的区间和大于等于target,记录当前长度,右指针继续右移,如果和值减去左指针的数大于target,那么左指针可以前移一位,继续移动右指针。

例1

target = 7
sum = 0
ans = 0
    L
    2 3 1 2 4 3
    R

sum = 2 小于7 移动右指针
    L
    2 3 1 2 4 3
      R
sum = 5 小于7 移动右指针
    L
    2 3 1 2 4 3
        R
sum = 6 小于7 移动右指针
    L
    2 3 1 2 4 3
          R
sum = 8 大于等于7 此时8-左指针指向的数2 < 7 左指针不变 移动右指针
ans = 4 记录长度为4
    L
    2 3 1 2 4 3
            R
sum = 12 大于等于712-左指针指向的数2 >= 7 左指针加1 
      L
    2 3 1 2 4 3
            R
sum = 10 大于等于712-左指针指向的数3 >= 7 左指针加1
        L
    2 3 1 2 4 3
            R  
sum = 7 大于等于7,此时7-左指针指向的数1 < 7 左指针不变, 右指针加1
        L
    2 3 1 2 4 3
              R
sum = 10 大于等于710-左指针指向的数1 >= 7 左指针加1
          L
    2 3 1 2 4 3
              R
sum = 9 大于等于79-左指针指向的数2 >= 7 左指针加1
            L
    2 3 1 2 4 3
              R
sum = 7 大于等于7 此时7-左指针指向的数3 < 7 左指针不变 移动右指针
ans = 2 记录长度为2
走完流程,最终结果取2为符合条件的最短子数组长度

代码

var minSubArrayLen = function(target, nums) {
    let l = 0, now = 0, ans = Infinity;
    for (let i = 0; i < nums.length; i++) {
        now += nums[i]
        while(l < i && now - nums[l] >= target) {
            now -= nums[l]
            l++
        }

        if (now >= target) {
            ans = Math.min(ans, i - l + 1)
        }
    }
    if (ans == Infinity) return 0
    return ans
};