双指针的变体:滑动窗口与长度最小的子数组问题

简介: 滑动窗口是一种高效的双指针技巧,常用于解决数组或字符串中的连续子区间问题。通过维护一个由 left 和 right 指针界定的窗口,动态调整其大小,以寻找满足特定条件的最优解。它常用于求解连续子数组的最值、字符子串判断等,如“长度最小的子数组”、“水果采摘”、“最小覆盖子串”等问题。核心思想是:在满足条件时收缩窗口,在不满足时扩展窗口,结合哈希表等结构维护窗口内状态,从而实现线性时间复杂度 O(n) 的高效求解。掌握滑动窗口的关键在于理解其模板结构,并灵活应对不同题目的状态维护需求。

今天复习了“长度最小的子数组”这道题,突然对滑动窗口这个技巧有了更深的理解。滑动窗口其实是双指针的一种变体,它用两个指针(一般叫 left 和 right)维护一个区间(也可以理解为一个“窗口”),根据题目的不同需求,动态地调整窗口的左右边界。

有趣的是,虽然代码里可能用了两个循环,但滑动窗口的时间复杂度依然是 O(n)。这是因为每个元素最多被“看”两次:一次被 right 扫进去窗口,一次被 left 从窗口移出去。因此整体上仍然是线性时间。

什么时候使用滑动窗口?
滑动窗口特别适合在一个连续区间内寻找某种性质的问题,比如:
连续子数组的最大/最小长度
连续子串是否包含某些字符
一段区间内最多/最少包含多少种元素
你可以把它想象成一扇在数组上移动的窗户,这扇窗户只关心“窗户里的内容”是否满足某种条件。一旦满足,就尝试收缩窗户(优化结果);不满足,就扩展窗户(继续寻找)。

滑动窗口的基本用法
滑动窗口的核心步骤其实很固定,基本可以套模板:
初始化窗口的两个边界:left 和 right
不断移动右边界 right,扩大窗口,直到满足条件
当条件满足后,尝试移动左边界 left,缩小窗口,同时记录最优结果
重复上述过程,直到右边界走到尽头

例题分析一:长度最小的子数组
这道题是滑动窗口的经典题型:
给你一个整数数组 nums 和一个整数目标值 target,请你找出数组中 总和 大于等于 target 的 最短子数组 的长度,并返回该长度。如果不存在符合条件的子数组,返回 0。
这个题目的关键点是:子数组必须是连续的,并且我们要在所有满足条件的子数组中找到最短的一个。
所以思路就是:

移动右指针,不断累加窗口内的和

一旦窗口内的和 ≥ target,就尝试移动左指针缩小窗口

每次满足条件时,更新最小长度

虽然是两个指针嵌套循环,但每个指针只会走一遍数组,所以时间复杂度仍是 O(n)。

例题分析二:Total Fruit(最多采几棵树的水果)
这题和长度最小子数组很像,也是滑动窗口。不同的是这题需要统计种类数量,而不是数值总和。
在 Python 中可以用 Counter() 或字典来维护窗口内每种水果的数量。
每次移动右指针采一棵水果,同时把它记录进字典。如果种类超过两种,就移动左指针,并更新字典(数量减1,为0就 pop 掉)。最终记录窗口的最大长度就是答案。

例题分析三:最小覆盖子串(minWindow)
这道题是滑动窗口中难度稍高的一道,很多人(包括我)第一次做都卡在了字典的使用上。
题目要求:
给两个字符串 s 和 t,返回 s 中最短的包含所有 t 中字符的子串(包括重复的字符)。
关键点是:我们不仅要知道有没有这个字符,还要知道每个字符的数量是否足够,因此用了两个 Counter() —— 一个记录 t 中每个字符需要的数量,一个实时记录窗口中字符的数量。
在滑动窗口的过程中,我们还需要一个额外的变量 start 来记录当前“最短窗口”的起始位置。如果找到更短的覆盖,就更新 start 和 min_len。
这也是我第一次意识到,滑动窗口虽然是模板化的写法,但遇到不同的题,窗口里需要维护的状态可能完全不同(和哈希表配合使用是很常见的变体)。

做题久了我还意识到,如果你对 dict、Counter 这些基本结构不熟,就会很难写出滑动窗口的变种。比如我之前卡在 totalFruit 和 minWindow,就是因为不知道怎么去维护窗口里的状态。

目录
相关文章
|
12月前
从刷题中抽象出来的二分法思维模型
本文总结了二分法的核心理解与应用技巧,探讨了其适用条件与逻辑构建方法。通过明确单调性与边界性质,帮助读者从“凭感觉写”进阶到“有依据设计”,提升对查找、边界与插入位置等问题的掌控力。
342 1
|
10月前
|
人工智能 自然语言处理 物联网
MCP+LLM+Agent:企业AI落地的新基建设计
MCP+LLM+Agent构建企业AI黄金三角架构,破解数据孤岛、工具碎片化与决策滞后难题。LLM负责智能决策,Agent实现自动执行,MCP打通数据与工具,助力企业实现从智能思考到业务闭环的跃迁。
|
文字识别 计算机视觉 Python
我用 Python 写了一个自动裁剪答题卡区域的小工具(附代码)
本文分享了一种通过 OpenCV 自动裁剪答题卡中答题区域的方法。核心思路是利用答题区域四周的黑色角块进行定位:先通过自适应阈值增强对比度,再用 `cv2.findContours()` 找轮廓,并计算每个轮廓的“紧凑度”(面积 / 周长)筛选出接近方块的角块。最终根据四个角块的边界矩形裁剪出答题区。代码实现详细,适合初学者参考,同时提供了参数调整建议以适配不同图像条件。
458 10
|
10月前
|
算法
今天的刷题记录:螺旋矩阵、区间和、开发商购买土地
本篇介绍了三个经典算法问题:螺旋矩阵通过控制边界按圈遍历;区间和利用前缀和优化求和;开发商买地则采用二维前缀和思想,枚举最优切割方式。三题均注重优化思路与边界处理。
149 0
|
10月前
|
传感器 机器学习/深度学习 Oracle
2025如何通过智能物资管理工具实现降本增效?核心功能实现路径!
本文探讨了基于物联网与决策科学的现代物资管理系统架构,分析了物资管理工具从静态台账向智能中枢演进的技术路径。通过“感知-决策-执行”三层架构、多模态感知与自适应预测等关键技术,实现库存优化与智能调度。结合主流工具选型与实施策略,揭示物资管理向自感知、自优化方向发展的未来趋势。
506 0
|
11月前
使用双指针法移除元素
双指针技巧常用于原地筛选数组中的有效元素,例如移动零、移除指定元素、去重等题目。这类问题核心在于使用快慢指针遍历并保留符合条件的值,压缩无效数据,达到题目要求。识别关键词如“原地操作”、“不能使用额外空间”、“删除某些元素”即可判断是否适用该模型。
138 0
|
10月前
|
人工智能