# [209] 长度最小的子数组
给定一个含有 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
提示:
进阶:
如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。
这道题是求满足条件的子数组最小长度。对于求子串、子数组的最优解问题,我们首先想到是否能用滑动窗口或是动态规划来解。这道题要求子数组连续,那么其实用滑动窗口就够了。
那么就来到了经典的问题填空环节:
扩充右边界后,何时能使滑动窗口内的元素满足要求。根据题意,当滑动窗口内元素总和 >= target 时,考虑开始缩小左边界。
何时更新返回结果。在本题中,当滑动窗口内元素总和 >= target 时,比对记录值与当前sum结果,保存最小值。
这样一套操作下来,整个问题就没有任何难点可言了。
(吐槽一句,题目是要笑死我吗,实现了O(n)的算法,为啥还要我设计一个O(nlgn)的算法……)
function minSubArrayLen(target: number, nums: number[]): number {
let res: number = nums.length + 1;
let left = 0;
let right = 0;
let sum = 0;
while (right < nums.length) {
sum += nums[right];
right += 1;
while (sum >= target) {
res = Math.min(res, right - left);
sum -= nums[left];
left++;
}
}
// 不存在时返回0
return res === nums.length + 1 ? 0 : res;
}