【Classic 150 刷题计划】 LeetCode 209. 长度最小的子数组 | C++ 滑动窗口(毛毛虫算法)经典模板

LeetCode 209. 长度最小的子数组

📌 题目描述

题目级别:中等

给定一个含有 n 个 正整数 的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

  • 示例 1:
    输入:target = 7, nums = [2,3,1,2,4,3]
    输出:2
    解释:子数组 [4,3] 是该条件下的长度最小的子数组。

💡 破题思路:滑动窗口 (Sliding Window)

这道题之所以能用滑动窗口,核心底气在于题目规定了数组里全是**"正整数"**。这意味着:

  • 窗口向右扩展(包含更多元素),总和一定变大。
  • 窗口向左收缩(吐出已有元素),总和一定变小。

这就像一条毛毛虫在数组上爬行。

算法步骤:

  1. 窗口扩张(找可行解) :定义左右指针 l 和 r,初始都在 0。让右指针 r 不断向右移动,把扫过的数字吞进肚子里(累加到 sum)。
  2. 窗口收缩(求最优解) :一旦发现肚子里的总和 sum >= target,说明我们找到了一个合法的子数组!此时先记录一下当前窗口的长度。然后,为了寻找**"更短"**的可能,我们尝试让左指针 l 向右移动,把左边的数字吐出来,直到 sum < target 为止。
  3. 交替进行 :r 负责探路寻找达标的区间,l 负责在达标后拼命压缩区间的长度,两者同向而行,绝不回头。

💻 C++ 代码实现 (原汁原味作者版)

cpp 复制代码
class Solution {
public:
    int minSubArrayLen(int target, std::vector<int>& nums) {
        int n = nums.size();
        
        // len 初始设为 -1,巧妙地代表"尚未找到任何合法子数组"的初始状态
        int sum = 0, len = -1, l = 0;

        // 1. 窗口扩张:右指针 r 负责探路吞并元素
        for (int r = 0; r < n; r ++ )
        {
            sum += nums[r];

            // 2. 窗口收缩:一旦总和达标,尝试移动左边界榨取更短的长度
            while (sum >= target)
            {
                // 如果是第一次找到 (len == -1),或者找到了更短的区间,则更新 len
                if (len == -1 || r - l + 1 < len) len = r - l + 1;
                
                // 左指针吐出元素,然后向右走一步
                sum -= nums[l];
                l ++ ;
            }
        }

        // 3. 收尾:如果 len 还是 -1,说明全程没达到过 target,返回 0
        return len == -1 ? 0 : len;
    }
};
相关推荐
汉克老师4 小时前
GESP2026年9月认证C++七级( 第一部分选择题(8~15题)精讲
c++·gesp·小学生·学c++编程
Mr_Macallon4 小时前
C++回顾(基础)(01)
c语言·开发语言·c++·学习
垆边人似月.4 小时前
任务混部(200 分档)
算法
言乐64 小时前
Python区分广度优先深度优先宽度优先的区别
python·算法·深度优先·广度优先·宽度优先
Rnan-prince4 小时前
LeetCode 股票买卖系列:一个动态规划状态机模板通吃四题
leetcode·动态规划
如意猴4 小时前
【C++】007 C/C++ 内存管理机制、malloc与new的区别及模板初阶
java·c++·算法
朝朝辞暮i4 小时前
C++ 第 32 课:main()、rclcpp::init()、spin()、shutdown()
开发语言·c++·算法
汉克老师4 小时前
GESP2026年9月认证C++一级( 第三部分编程题(1、新龟兔赛跑))精讲
c++·gesp·小学生·学c++编程
圣保罗的大教堂5 小时前
leetcode 3756. 连接非零数字并乘以其数字和 II 中等
leetcode
沫璃染墨5 小时前
《从零入门Linux系统篇(五十七):线程篇·十——生产者消费者模型进阶:从环形缓冲区到POSIX信号量》
linux·运维·服务器·开发语言·c++·系统架构·信号处理