题目
给定一个含有 n 个正整数的数组和一个正整数 target,找出该数组中满足其和 ≥ target 的长度最小的 连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0
输入: target = 4, nums = [1,4,4] 输出: 1
题解
第一种
我们这里先采用暴力枚举进行实现,首先我们在函数中接受两个参数,一个数字s和一个数组nums,在函数使用两个指针i和j分别表示子数组的起始位置和终止位置,默认值我们先设为0,在函数使用一个变量minl来记录当前找到的最小子数组的长度,初始值为数组nums的长度加1,在函数中我们使用一个while循环来遍历数组nums,在循环中,我们首先计算从i开始的连续j个元素的和total,如果total大于等于s,我们则更新minl的值为min,如果total小于s,我们则继续向右移动j,直到total大于等于s或者j超出数组范围为止,如果minl的值没有被更新,则说明找不到符合条件的子数组,最后我们将minl变量返回出去即可
var minSubArrayLen = function (s, nums) { let minl = nums.length + 1 for (let i = 0; i < nums.length; i++) { let total = nums[i] let j = 1 while (total < s && i + j < nums.length) { total += nums[i + j] ++j } if (total >= s) { minl = Math.min(minl, j) } } if (minl === nums.length + 1) { minl = 0 } return minl }
第二种
我们这里还可以采用双指针方式进行实现,我们在函数中先使用两个指针start和end分别代表子数组的起始位置和终止位置,初始值我们先设为0,函数中我们使用一个变量sum来记录当前子数组的元素之和,值为0,使用一个变量minLen来记录当前找到的最小子数组的长度,初始值为正无穷,接下来我们在函数中使用while循环进行遍历数组nums,循环中我们首先计算从start到end的元素之和sum,如果sum小于s,我们则将end右移一位,继续向右扩展子数组,如果sum大于等于s,我们则更新minLen的值为min,然后我们将start右移一位并将sum减去移除的第一个元素和移动后的第一个元素,这样就得到了一个新的子数组,继续判断其元素之和是否大于等于s,最后如果minLen的值没有被更新,则说明找不到符合条件的子数组返回0否则返回minLen即可
var minSubArrayLen = function (s, nums) { let start = 0 let end = 0 let sum = 0 let minLen = +Infinity while (end < nums.length) { sum = sum + nums[end] if (sum < s) { end++ } else { minLen = Math.min(minLen, end - start + 1) sum = sum - nums[start] - nums[end] start++ } } return minLen == +Infinity ? 0 : minLen }