leetcode-数组-209.-长度最小的子数组

101 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

Hi, 大家好。我是新人,程序员库里。

今后会按类分享算法题。

今天给大家分享第13道leetcode上数组中使用双指针相关的算法题。

209. 长度最小的子数组

leetcode地址:leetcode-cn.com/problems/mi…

难度

中等

描述

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

解法

1.采用滑动窗口的原理

2.定义左指针left,初始值为0

3.定义右指针rihgt, 初始值为-1,因为要保证初始的窗口[left...right]中没有值

4.定义变量sum,表示连续子数组的和,初始值为0

5.定义变量res,表示最小子数组的长度,初始值为 nums.length + 1, 因为要找到最小的,所以初始定义为一个不可能出现的结果,在找最小子数组的过程中,res会慢慢减小

6.开始进行while循环,条件是当left < nums.length的时候,因为滑动窗口是向右移动,保证左指针可以移动

7.在遍历过程中,当sum小于target的时候,因为要找到sum >= target的数组,所以需要将滑动窗口向右移动一位,就说right++,同时需要将sum加上right指向的元素。

8.否则sum 大于 target的时候,表明找到一个连续子数组,使得 sum >= target,但是不一定是长度最小的。所以需要将 sum 减去 left指向的元素,缩小滑动窗口,即lef向右移动一位,即left++

9.在这个滑动的过程中,记录sum值,当滑动到最后的时候,当sum>=target的时候,只需取res和和滑动窗口长度的最小值。最后返回res即可

10.当遍历完,没有找到res的最小值,也就是滑动完后,res还是等于nums.length-1,返回0即可

代码

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let left = 0, right = -1;
    let sum = 0;
    let res = nums.length + 1;
    while(left < nums.length){
        if(right + 1 < nums.length && sum < target){
            right++
            sum +=nums[right]
        }else{
            sum -= nums[left]
            left++
        }

        if(sum >= target){
            res = Math.min(res , right - left + 1)
        }
    }
    if(res === nums.length + 1) return 0

    return res;
};