0209.长度最小的子数组

难度:🟡 中等

标签数组二分查找前缀和滑动窗口

链接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

解题思路

核心思想

本题的目标是在一个只包含正整数的数组中,找到一个和大于等于 target 的、长度最短的连续子数组。由于所有元素都是正数,子数组的和会随着其长度的增加而单调递增,这为我们使用滑动窗口提供了完美的基础。

思路选择

滑动窗口法 是解决此问题的标准最优思路。

  • 我们可以使用两个指针,left(窗口左边界)和 right(窗口右边界),来定义一个“窗口”。

  • right 指针负责向右移动,不断地将新元素纳入窗口,并累加到窗口的和 sum 中。

  • 一旦窗口内的和 sum 达到了 target 的要求,我们就找到了一个满足条件的子数组。此时,我们记录下它的长度,并尝试收缩窗口——即让 left 指针向右移动,并从 sum 中减去移出的元素。

  • 我们持续收缩窗口,直到 sum 不再满足 >= target 的条件,然后再继续移动 right 指针扩大窗口,如此往复,直到 right 遍历完整个数组。

关键步骤

  1. 初始化

    • left = 0, right = 0

    • 窗口内元素和 sum = 0

    • 最小长度 minLength = Infinity

  2. 扩展窗口:外层循环控制 right 指针从头到尾遍历数组。 a. 将 nums[right] 加入 sum

  3. 收缩窗口:内层 while 循环检查 sum 是否大于等于 target。 a. 如果是,则更新 minLength = Math.min(minLength, right - left + 1)。 b. 从 sum 中减去 nums[left],并将 left 指针右移一位,完成窗口的收缩。

  4. 返回结果:外层循环结束后,如果 minLength 仍然是 Infinity,说明没有找到任何满足条件的子数组,返回 0。否则,返回 minLength

代码实现

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function (target, nums) {
    let left = 0, right = 0, minLen = Infinity, sum = 0;

    // right 指针负责扩展窗口
    while (right < nums.length) {
        sum += nums[right];
        right++; // 注意:这里 right 已经指向了窗口外的下一个元素

        // sum 满足条件后,收缩窗口
        while (sum >= target) {
            // 此时窗口长度是 right - left
            minLen = Math.min(minLen, right - left);
            sum -= nums[left];
            left++;
        }
    }
    return minLen === Infinity ? 0 : minLen;
};

复杂度分析

  • 时间复杂度O(n) 其中 n 是数组 nums 的长度。leftright 两个指针都最多只会遍历整个数组一次。

  • 空间复杂度O(1) 我们只使用了常数个额外变量,空间消耗是恒定的。

相关题目

总结

本题是滑动窗口算法的经典应用之一。该算法的核心在于通过两个指针维护一个可变窗口,并根据窗口内的状态来决定是扩展还是收缩窗口,从而在线性时间内找到满足特定条件的最佳子数组或子串。

Copyright © Jun 2025 all right reserved,powered by Gitbook该文件修订时间: 2025-07-03 17:35:08

results matching ""

    No results matching ""

    results matching ""

      No results matching ""