Leetcode前端必会系列:长度最小子数组

68 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情

引言

算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。

题目描述

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

 

提示:

  • 1 <= target <= 109
  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105

分析

根据题目的分析,我们如何设计求长度最小的子数组?可以使用双指针动态的判断累加的和,比较轻松的解决问题了。可以按照如下的步骤进行设计。

  1. 使用双指针,开始的标记一个,然后从第二关开始标记
  2. 累加和,如果超出了目标值,然后从第一个指针向上走
  3. 判断最小长度的数组。
  4. 返回最后的最小结果。

解答

   /**

 * @param {number} target

 * @param {number[]} nums

 * @return {number}

 */

var minSubArrayLen = function(target, nums) {

    let begin = 0

  let sum = 0

  let min = Number.MAX_VALUE

  for(let i=0;i<nums.length;i++) {

    sum += nums[i]

    while(sum>=target) {

      min = Math.min(min,i-begin+1)

      sum -= nums[begin]

      begin++

    }

  }

  return min===Number.MAX_VALUE?0:min

};
   

根据代码,我们发现长度最小的子数组是比较容易的。动态的使用双指针标记完成题目的设计就可以了。