当前位置: 首页 > news >正文

【算法复习】滑动窗口(同向区间指针)

滑动窗口(同向区间指针)

滑动窗口是数组 / 字符串类题目里出镜率极高的套路。掌握它,能让一大批看似 O(n²) 的暴力解法瞬间降到 O(n)。本文从"定长"和"变长"两个视角,配合可直接套用的模板代码,帮你一次性理清思路。

一、什么是滑动窗口?

滑动窗口(Sliding Window)属于双指针中的一种——同向指针。两个指针leftright同时从数组左端出发,向右移动,圈出一个不断变化的"窗口"。

它的核心思想是:在窗口滑动的过程中,利用已经计算好的信息,避免重复计算。

根据窗口大小是否固定,可以分为两类:

类型窗口大小典型问法
定长滑动窗口固定为k“长度为 k 的子数组/子串中……的最大/最小值”
变长滑动窗口动态变化“满足 XX 条件的最长/最短子数组”

二、定长滑动窗口(固定相框)📷

想象你拿着一个尺寸固定的相框,在数组上从左往右一格一格地平移。每移动一次,画面里就进来一个新元素,挤出去一个老元素

套路三步走

  1. 初始化:先计算前k个元素构成的第一个窗口的状态(和、计数、最大值等)。
  2. 滑动:窗口整体向右平移,每次加一个新进来的nums[i],减一个被踢出去的nums[i-k]
  3. 更新答案:在每次滑动后记录当前窗口的结果。

全程只需一层循环,时间复杂度 O(n)。

模板代码

// 1. 初始化第一个长度为 k 的窗口 let sum = 0; for (let i = 0; i < k; i++) { sum += nums[i]; // 累加状态 } let res = sum; // 2. 开始滑动 for (let i = k; i < nums.length; i++) { // 进一个 nums[i],出一个 nums[i-k] sum += nums[i] - nums[i - k]; // 更新最大/最小值 res = Math.max(res, sum); } return res;

典型例题

  • 🔹LeetCode 643:子数组最大平均数 I
  • 🔹LeetCode 1456:定长子串中元音的最大数目
  • 🔹LeetCode 2090:半径为 k 的子数组平均值

三、变长滑动窗口(毛毛虫)🐛

变长窗口更像一只毛毛虫:头(right)先往前拱一拱,拱到不舒服了,尾巴(left)再跟上来缩一缩,如此反复向前爬行。

套路要点

  • 外层循环:右指针right不断向右拉伸,把新元素纳入窗口。
  • 内层循环:一旦窗口满足/违反某种条件,左指针left立即向右收缩,直到条件恢复。
  • 关键:根据题目要求的是"最长"还是"最短",决定在收缩之前还是之后更新答案。

💡小技巧

找最短→ 在 while 内部(窗口刚满足条件时)更新答案,然后继续缩;
找最长→ 在 while 外部(窗口刚恢复合法时)更新答案。

模板代码

let left = 0, right = 0; let res = 0; // 或 Infinity,视题意而定 while (right < nums.length) { // 【1】入窗:扩展右边界 // 把 nums[right] 加入窗口,更新状态 while (/* 窗口需要收缩 */) { // 【2】记录答案:找「最短」时在这里更新 res // 【3】出窗:收缩左边界 // 把 nums[left] 移出窗口,更新状态 left++; } // 【4】记录答案:找「最长」时在这里更新 res right++; } return res;

典型例题

  • 🔹LeetCode 209:长度最小的子数组(找最短)
  • 🔹LeetCode 3:无重复字符的最长子串(找最长)
  • 🔹LeetCode 76:最小覆盖子串(找最短 + 哈希计数)
  • 🔹LeetCode 438:找到字符串中所有字母异位词

四、使用滑动窗口的信号 🚦

当题目同时满足以下特征时,优先考虑滑动窗口:

  • 处理连续的子数组 / 子串 / 子序列。
  • 求满足某条件的最长 / 最短 / 定长区间。
  • 数据具有单调性:窗口扩大时某个指标单调变化(如和变大、字符种类变多)。

⚠️注意:如果数组中包含负数,窗口和就不再单调,此时滑动窗口可能失效,需要考虑前缀和 + 哈希表等其它思路。

http://www.cnnetsun.cn/news/2079202.html

相关文章:

  • 华为Mate50的卫星通信是怎么做到的?拆解那颗神秘的北斗短报文芯片
  • 告别盲猜!用ESP8266+INA226给你的DIY电源做个精准“体检”(附完整代码)
  • 别再为接口授权发愁:3 分钟搞定自动化账号登录
  • LSTM时间序列预测实战:从原理到洗发水销售预测
  • Z-Image-Turbo极速创作室全攻略:从部署到出图,一篇搞定
  • 从静态词嵌入到BERT上下文向量:NLP表征进化与应用
  • 2026年无需代码、新手小白只需两步集成OpenClaw教程
  • 凌晨3点,47个账号同时被封
  • DNS+DHCP实验(使用ENSP进行配置)
  • 2026年北京耳聋医院TOP5榜单揭晓
  • RWKV7-1.5B-World网络通信优化:解决高并发下的模型响应延迟问题
  • TCP-快速重传与超时重传的困惑解析
  • 适用震动场合,实现稳定测量:弗赛德抗震型热电阻
  • DeepSeek写的小说,prompt 是“写一个搞 大模型AI 的爽文男主小说,写 5 章内容,剧情搞笑好玩”
  • Qwen3-ASR-0.6B参数详解:6亿参数如何平衡精度与推理延迟
  • 中国家庭金融调查(chfs)区县码(2011-2019年)
  • 福利|AMD × LMCache:基于 AMD GPU 的 LMCache 推理加速
  • 华为 eNSP 防火墙实战:防火墙安全策略
  • 【开源推荐】form-validator-cn 轻量级中文表单校验库 | TS 零依赖、极简开箱即用
  • 2026 网络安全新手避坑全指南:从零入门到实战落地,彻底告别自学弯路
  • Python数据类型转换实现方法
  • 嵌入式系统最后防线:在无MMU的MCU上实现C语言内存安全的3种硬件协同方案(ARMv8-M TrustZone实测)
  • 从CAN总线到以太网:手把手拆解汽车‘五大域’控制器之间的‘聊天’协议
  • Skill生成能力测试
  • 算法训练营第十四天 | 18. 四数之和
  • 实时数字人领域迎来新突破,Soul App发布轻量化模型SoulX-FlashHead
  • IOU Tracker实战:在低算力边缘设备(如Jetson Nano)上部署车辆跟踪
  • AI拓客系统选型指南:从“生存刚需”到“增长引擎”,GEO技术成破局关键
  • SQL如何处理多级分类统计报表_窗口函数层级汇总技巧
  • 从LIDC-IDRI到可训练数据:Python实战放射组学肺结节良恶性分类的数据预处理全解