9.LeetCode 209. 长度最小的子数组 | 滑动窗口专题详解

目录

[1. 题目解析](#1. 题目解析)

[示例 1:](#示例 1:)

[示例 2:](#示例 2:)

[2. 算法原理](#2. 算法原理)

[解法一:暴力枚举所有子数组的和 ------ O(n²)](#解法一:暴力枚举所有子数组的和 —— O(n²))

[解法二:利用单调性,使用"同向双指针"来优化 ------ O(n)](#解法二:利用单调性,使用“同向双指针”来优化 —— O(n))

[✅ 怎么用?](#✅ 怎么用?)

图解过程:

正确性?

时间复杂度

[3. 编写代码](#3. 编写代码)

[OJ链接:​ https://leetcode.cn/problems/minimum-size-subarray-sum/description/](#OJ链接: https://leetcode.cn/problems/minimum-size-subarray-sum/description/)


1. 题目解析

本题来自 LeetCode 第 209 题:长度最小的子数组。

**题目描述:**​

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

找出该数组中满足其和 ≥ target的长度最小的 连续子数组 ​ [nums[l], nums[l+1], ..., nums[r-1], nums[r]],并返回其长度。如果不存在符合条件的子数组,返回 0。

示例 1:

java 复制代码
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下长度最小的子数组。

示例 2:

java 复制代码
输入:target = 4, nums = [1,4,4]
输出:1

📌 关键点:

  • 子数组必须是连续的

  • 要求和 ≥ target

  • 返回的是最小长度,不是子数组本身

  • 若不存在,返回 0


2. 算法原理

解法一:暴力枚举所有子数组的和 ------ O(n²)

通过双重循环枚举所有子数组,计算和并比较,时间复杂度为 O(n²),在数据规模大时会超时。


解法二:利用单调性,使用"同向双指针"来优化 ------ O(n)

这是本题的核心解法:滑动窗口(Sliding Window)

✅ 怎么用?

我们用两个指针 left和 right构建一个窗口 ,窗口内的元素和记为 sum,窗口长度记为 len。

步骤如下:

  1. 初始化:left = 0, right = 0

  2. 进窗口 ​ → right向右移动,将 nums[right]加入 sum

  3. 判断 ​ → 如果 sum >= target,说明当前窗口满足条件,尝试缩小窗口

    • 更新最小长度:len = min(len, right - left + 1)

    • 出窗口 ​ → left向右移动,sum -= nums[left++]

  4. 重复步骤 2~3,直到 right遍历完整个数组

图解过程:

以 target = 7, nums = [2,3,1,2,4,3]为例:

  • 初始:left=0, right=0, sum=0, len=+∞

  • right=0→ 进窗口:sum=2→ 不满足

  • right=1→ 进窗口:sum=5→ 不满足

  • right=2→ 进窗口:sum=6→ 不满足

  • right=3→ 进窗口:sum=8→ 满足!→ 更新 len=4,出窗口:sum=6, left=1

  • right=4→ 进窗口:sum=10→ 满足!→ 更新 len=4(当前窗口 3,1,2,4),出窗口:sum=8, left=2

  • right=5→ 进窗口:sum=11→ 满足!→ 更新 len=3(1,2,4),出窗口:sum=7, left=3

  • right=5→ 再次判断:sum=7 >=7→ 更新 len=2(2,4),出窗口:sum=3, left=4

  • 循环结束

✅ 最终最小长度为 2


正确性?

利用单调性,规避了很多没有必要的枚举行为

因为数组元素都是正整数 ,所以当 sum >= target时,我们移动 left指针一定能缩小窗口,且不会错过更优解。这是滑动窗口能成立的核心前提。


时间复杂度

  • right指针遍历数组一次 → O(n)

  • left指针也最多移动 n 次 → O(n)

  • 总体:O(n)

✅ 从 n+n → 2n → O(n),线性时间复杂度,非常高效!


3. 编写代码

以下是 Java 实现代码

java 复制代码
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length, sum = 0, len = Integer.MAX_VALUE;
        for (int left = 0, right = 0; right < n; right++) {
            sum += nums[right]; // 进窗口
            while (sum >= target) { // 判断
                len = Math.min(len, right - left + 1); // 更新结果
                sum -= nums[left++]; // 出窗口
            }
        }
        return len == Integer.MAX_VALUE ? 0 : len;
    }
}

可直接复制运行。

欢迎在评论区留言交流,我们一起把滑动窗口吃透!


OJ链接: ​ https://leetcode.cn/problems/minimum-size-subarray-sum/description/

祝你刷题顺利,早日拿Offer!++点个关注++

相关推荐
NE_STOP8 分钟前
Spring AI Alibaba - MCP入门
java
nice_lcj52011 分钟前
【从零理解 Spring AI · 07】对话记忆:让模型记住上一句说了什么
java·spring ai·ai应用开发·chatmemory·对话记忆
民乐团扒谱机1 小时前
【微实验】NSGA-II(非支配排序遗传算法)——解决多目标优化问题的“自然选择模拟器”
linux·人工智能·算法
SL_staff1 小时前
制造业交付崩盘?用跨部门节点协同计划打通销售、生产与质量链路
java·开源·产品
青少儿编程课堂1 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:中缀表达式求值解析
c++·python·算法·bfs·信息学竞赛
文丑颜不良啊2 小时前
LeetCode2261~2280题目解析
java·leetcode
SL_staff2 小时前
告别规则黑盒:JVS-Rules 在金融风控中的可视化决策编排实践
java·产品·全栈
逃逸线LOF3 小时前
服务网关Gateway
java·运维·gateway
灿飞屋3 小时前
Kotlin与Java虚拟机四:函数
java·python·kotlin·安卓·android jetpack
武子康3 小时前
Qwen-Drive 到底是什么:4B 级 VLM 如何成为驾驶策略底座
人工智能·算法·机器学习