一起养成写作习惯!这是我参与「掘金日新计划 · 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;
};