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

算法之滑动窗口

(一) 滑动窗口的定义   

       滑动窗口算法是一种高效处理数组 / 字符串中连续子序列(子数组、子字符串) 问题的技巧,滑动窗口算法是同向双指针(同向双指针在上一篇文章中,链接)算法的一个典型应用场景。核心思想是通过维护一个 “窗口”(由左右两个指针界定的连续区间),在遍历过程中动态调整窗口的边界,避免重复计算,从而将原本可能需要嵌套循环的 O (n²) 时间复杂度优化为 O (n)。 

核心特点

  • 窗口是连续的:窗口内的元素必须是原序列中连续的一段(如数组的子数组、字符串的子字符串)。
  • 动态调整边界:通过移动左指针(缩小窗口)或右指针(扩大窗口),覆盖所有可能的有效子序列。
  • 减少重复计算:避免对同一元素进行多次无效检查,仅关注窗口内的元素变化。

主要类型
根据窗口大小是否固定,分为两类:

1. 固定大小窗口

  • 窗口长度固定(如长度为 k),左右指针同时移动(右指针右移时,左指针也同步右移,保持窗口长度不变)。

2. 可变大小窗口

  • 窗口长度不固定,需根据条件动态调整(通常右指针先扩大窗口,满足条件后左指针再缩小窗口,寻找最优解)。

基本步骤(以可变窗口为例)

  1. 初始化左指针left=0,右指针right=0,用于界定窗口[left, right]。
  2. 移动右指针right,扩大窗口,直到窗口满足目标条件(如包含所有需要的元素)。
  3. 当窗口满足条件时,尝试移动左指针left,缩小窗口,同时更新最优解(如最短长度、最大长度等)。
  4. 重复步骤 2-3,直到右指针遍历完整个序列。

题目:长度最小的子数组

链接:209. 长度最小的子数组 - 力扣(LeetCode)

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

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

核心思想:

1. 暴力解法

      采用「顺序遍历」的方式,将数组中每个元素依次作为起始点。从该起始点开始向后查找,确定满足区间和「大于等于」目标值的最短子数组。最终在所有可能的起始点对应的结果中,选取长度最小的子数组作为解。

      但是时间复杂度为 O (n²),效率太低。

2. 优化解法(滑动窗口)

       滑动窗口解法的核心思路是:利用「连续区间」的特性,通过两个指针(左指针 left、右指针 right)维护一个动态变化的 “窗口”,高效寻找满足条件的最短子数组,避免暴力解法中的重复计算。
具体做法:

1. 初始化窗口

  • 左指针 left 和右指针 right 都从 0 开始,窗口为[left, right],用变量 sum 记录窗口内元素的和。

2. 扩大窗口

  • 先移动右指针,将元素加入窗口,累加 sum。此时窗口不断向右扩展,直到 sum >= target(窗口内元素和满足条件)。

3. 缩小窗口找最优解:

  • 当 sum >= target 时,说明当前窗口是一个有效解。但我们要找 “最短” 的子数组,因此尝试移动左指针,将窗口左侧的元素移除(sum 减去该元素),同时更新最小长度。

(这一步的关键:因为数组元素都是正数,移除左侧元素后,sum 可能仍然满足 >=target,但窗口长度更短,所以需要持续缩小窗口直到 sum < target 为止)。

4. 重复扩展与缩小

  • 右指针继续向右移动,重复步骤 2-3,直到右指针遍历完整个数组。

为什么滑动窗口效率更高?
        暴力解法中,每个起始位置都要重新累加元素和,存在大量重复计算(比如从 i=0 开始计算过 [0,3] 的和,从 i=1 开始又要重新计算 [1,3] 的和)。

而滑动窗口中:

  • 右指针和左指针都只单向移动(从不回退),每个元素最多被加入窗口一次、移出窗口一次,总共操作次数为 O (n)。
  • 窗口的 sum 是基于上一次的计算结果更新的(加右元素或减左元素),避免了重复累加,因此时间复杂度降至 O (n)。

最终,通过这种 “先扩展找可行解,再缩小找最优解” 的方式,能高效找到满足条件的最短子数组长度;若不存在则返回 0。

代码:

1. 暴力解法

//长度最小的子数组暴力解法
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size();int len = INT_MAX;for (int i = 0; i < n; i++){int sum = 0;for (int j = i; j < n; j++){sum += nums[j];if (sum >= target){len = min(len, j - i + 1);break;}}}return len == INT_MAX ? 0 : len;}
};

2. 优化解法(滑动窗口)

//长度最小的子数组优化解法
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size(), sum = 0, len = INT_MAX;for (int left = 0, right = 0; right < n; right++){sum += nums[right];while (sum >= target){len = min(len, right - left + 1);sum -= nums[left++];}}return len == INT_MAX ? 0 : len;}
};

以上就是算法之滑动窗口的学习一点点,后续的会继续更新这个算法的题目,我们将留待日后进行。希望这些知识能为你带来帮助!如果觉得内容实用,欢迎点赞支持~ 若发现任何问题或有改进建议,也请随时与我交流。感谢你的阅读!(因为博主上学了不太方便一次性更完有点太耗费时间)


文章转载自:

http://FUaiRvcs.jpmcb.cn
http://VtN7VpnN.jpmcb.cn
http://1qz3f490.jpmcb.cn
http://cSRsllra.jpmcb.cn
http://Os42xHVa.jpmcb.cn
http://fXAz6gvP.jpmcb.cn
http://Joi7p3mU.jpmcb.cn
http://qsel8vpr.jpmcb.cn
http://g8bvSkbl.jpmcb.cn
http://YWmWfPBX.jpmcb.cn
http://ePrppPhF.jpmcb.cn
http://CB9jb9OR.jpmcb.cn
http://Q8kS07NI.jpmcb.cn
http://rk78Ozcf.jpmcb.cn
http://QVC590jF.jpmcb.cn
http://kXu8cnRb.jpmcb.cn
http://AQWDphZ0.jpmcb.cn
http://hcAGUhWn.jpmcb.cn
http://LA4mPzjC.jpmcb.cn
http://c11wliZd.jpmcb.cn
http://B8MEnAKr.jpmcb.cn
http://PdcrSEkn.jpmcb.cn
http://mFjfqRTb.jpmcb.cn
http://jyzoCjj7.jpmcb.cn
http://EpxeMoe8.jpmcb.cn
http://hl6CoQaD.jpmcb.cn
http://SditLY45.jpmcb.cn
http://Wzoqsyvx.jpmcb.cn
http://08zrZdcJ.jpmcb.cn
http://ysv8beTd.jpmcb.cn
http://www.dtcms.com/a/373363.html

相关文章:

  • 解决 GitHub SSH 连接超时问题
  • 服务器文件同步用哪个工具?介绍一种安全高效的文件同步方案
  • SOME/IP-SD(Service Discovery)协议的核心协议
  • Claude-Flow 使用指南
  • SpringMVC 工作原理
  • Oracle高可用与容灾解决方案
  • 玳瑁的嵌入式日记D33-0908(SQL数据库)
  • GISBox内置GIS服务器:从数据导入到场景化应用的全流程
  • 基于Python+Streamlit的旅游数据分析与预测系统:从数据可视化到机器学习预测的完整实现
  • 【硬件-笔试面试题-69】硬件/电子工程师,笔试面试题(知识点:电机驱动电路的反馈电路)
  • 【Ansible】实施 Ansible Playbook知识点
  • 汽车电子软件 --- 架构演进与挑战突破之路
  • 13、做中学 | 初一下期 Golang数组与切片
  • Linux系统:线程的互斥和安全
  • # 集成学习完整指南:从理论到实践
  • CSS rem单位
  • 云原生与 AI 加持下,DevOps平台的演进趋势、选型建议与推荐指南
  • 软件研发如何选对方法论?传统计划驱动与敏捷价值驱动的全面对比
  • CVE-2025-57052:cJSON库存在CVSS 9.8高危JSON解析漏洞(含PoC)
  • 基于大数据的二手交易推荐系统设计与实现(代码+数据库+LW)
  • 9.8 ajax+php基础语法
  • USB系统学习笔记 - 从概念到抓包解析
  • 前端框架对比分析:离线PWA + Cloudflare Workers部署
  • TensorFlow深度学习实战(37)——深度学习的数学原理
  • iOS混淆工具实战,健身与健康监测类 App 的隐私与算法保护
  • ChatAI项目-ChatGPT-SDK组件工程
  • 关于对逾期提醒的定时任务~改进完善
  • BKY(莱德因):基于线粒体靶向的细胞级御龄科学实践
  • 学习日记-SpringMVC-day50-9.8
  • VUE3加载cesium,导入czml的星座后页面卡死BUG 修复