算法07-滑动窗⼝算法

滑动窗口算法(Sliding Window)

一、详细讲解

A、一句话总结

滑动窗口算法是一种通过维护一个动态窗口来解决问题的技巧,窗口在数据上“滑动”,逐步找到最优解。


B、核心思想

想象你在看一列火车,火车窗口只能看到一部分车厢。滑动窗口算法就是通过调整窗口的起点和终点,找到你感兴趣的部分(比如最长的连续车厢、最短的覆盖范围等)。


C、适用场景

滑动窗口算法通常用于解决以下问题:

  1. 子数组/子字符串问题:比如找最长的无重复字符子串、最短的覆盖子串等。
  2. 连续区间问题:比如找满足条件的连续子数组。
  3. 优化问题:比如在固定窗口大小内找最大值、最小值或平均值。

D、滑动窗口的两种类型

1. 固定大小的窗口
  • 窗口大小固定,比如每次只看连续的 3 个元素。
  • 例子:计算数组中每个长度为 k 的子数组的平均值。
2. 可变大小的窗口
  • 窗口大小不固定,根据条件动态调整。
  • 例子:找最长的无重复字符子串。

E、滑动窗口的基本步骤

  1. 初始化窗口

    • 定义窗口的起点(left)和终点(right),通常初始化为 0。
    • 定义一些辅助变量(比如当前窗口的和、最大值、最小值等)。
  2. 滑动窗口

    • 移动右边界(right),扩大窗口,直到满足某个条件。
    • 移动左边界(left),缩小窗口,直到不满足条件。
    • 在滑动过程中,记录需要的结果(比如最大长度、最小长度等)。
  3. 返回结果

    • 根据滑动过程中记录的结果,返回最终答案。

F、关键特点

  1. 高效:通过滑动窗口,避免了重复计算,时间复杂度通常为 (O(n))。
  2. 灵活:适用于多种问题,尤其是需要处理连续区间的问题。
  3. 双指针:滑动窗口通常用双指针(leftright)来实现。

G、举个实际例子

问题:找最长的无重复字符子串
  • 比如字符串 "abcabcbb",最长的无重复字符子串是 "abc",长度为 3。
  • 滑动窗口的过程:
    1. 初始化窗口:left = 0right = 0
    2. 移动 right,直到遇到重复字符(比如 'a' 重复)。
    3. 移动 left,缩小窗口,直到重复字符被排除。
    4. 重复上述过程,记录最大长度。

H、滑动窗口的优缺点

优点
  • 时间复杂度低,通常为 (O(n))。
  • 代码简洁,逻辑清晰。
  • 适用于多种连续区间问题。
缺点
  • 需要仔细设计窗口的移动规则。
  • 对非连续区间问题不适用。

I、时间复杂度和空间复杂度

  • 时间复杂度:通常为 (O(n)),因为每个元素最多被访问两次(leftright 各一次)。
  • 空间复杂度:通常为 (O(1)) 或 (O(n)),取决于是否需要额外的数据结构(比如哈希表)。

J、实际应用场景

  1. 字符串处理:比如找最长的无重复字符子串、最短的覆盖子串。
  2. 数组处理:比如找满足条件的连续子数组、固定大小的滑动窗口最大值。
  3. 数据分析:比如计算滑动窗口内的平均值、最大值、最小值。

K、总结

滑动窗口算法就像“望远镜”,通过调整窗口的大小和位置,找到你感兴趣的部分。它的核心是双指针动态调整窗口,适合解决连续区间问题,既高效又灵活!

二、滑动窗口算法示例:找最长的无重复字符子串

A、问题描述

给定一个字符串,找出其中不含有重复字符的最长子串的长度。

示例

输入:"abcabcbb"
输出:3
解释:最长的无重复字符子串是 "abc",长度为 3。


B、滑动窗口算法实现

核心思路
  1. 使用双指针 leftright 表示窗口的左右边界。
  2. 使用哈希集合(set)记录窗口内的字符,确保无重复。
  3. 移动 right 扩大窗口,如果遇到重复字符,则移动 left 缩小窗口。
  4. 在滑动过程中,记录窗口的最大长度。

C、分步图示演示

以下是对字符串 "abcabcbb" 的分步演示:

初始状态
字符串:a b c a b c b b
索引: 0 1 2 3 4 5 6 7
窗口:[]
left = 0, right = 0
最大长度:0

步骤 1:right = 0,字符 ‘a’
  • 字符 ‘a’ 不在集合中,加入集合。
  • 更新窗口:[a]
  • 更新最大长度:1
窗口:[a]
left = 0, right = 0
最大长度:1

步骤 2:right = 1,字符 ‘b’
  • 字符 ‘b’ 不在集合中,加入集合。
  • 更新窗口:[a, b]
  • 更新最大长度:2
窗口:[a, b]
left = 0, right = 1
最大长度:2

步骤 3:right = 2,字符 ‘c’
  • 字符 ‘c’ 不在集合中,加入集合。
  • 更新窗口:[a, b, c]
  • 更新最大长度:3
窗口:[a, b, c]
left = 0, right = 2
最大长度:3

步骤 4:right = 3,字符 ‘a’
  • 字符 ‘a’ 已经在集合中,需要移动 left
  • 移动 left 到 1,移除字符 ‘a’。
  • 更新窗口:[b, c, a]
  • 最大长度保持不变:3
窗口:[b, c, a]
left = 1, right = 3
最大长度:3

步骤 5:right = 4,字符 ‘b’
  • 字符 ‘b’ 已经在集合中,需要移动 left
  • 移动 left 到 2,移除字符 ‘b’。
  • 更新窗口:[c, a, b]
  • 最大长度保持不变:3
窗口:[c, a, b]
left = 2, right = 4
最大长度:3

步骤 6:right = 5,字符 ‘c’
  • 字符 ‘c’ 已经在集合中,需要移动 left
  • 移动 left 到 3,移除字符 ‘c’。
  • 更新窗口:[a, b, c]
  • 最大长度保持不变:3
窗口:[a, b, c]
left = 3, right = 5
最大长度:3

步骤 7:right = 6,字符 ‘b’
  • 字符 ‘b’ 已经在集合中,需要移动 left
  • 移动 left 到 5,移除字符 ‘a’ 和 ‘b’。
  • 更新窗口:[c, b]
  • 最大长度保持不变:3
窗口:[c, b]
left = 5, right = 6
最大长度:3

步骤 8:right = 7,字符 ‘b’
  • 字符 ‘b’ 已经在集合中,需要移动 left
  • 移动 left 到 7,移除字符 ‘c’ 和 ‘b’。
  • 更新窗口:[b]
  • 最大长度保持不变:3
窗口:[b]
left = 7, right = 7
最大长度:3

D、最终结果

遍历结束后,最大长度为 3,对应的子串是 "abc"


E、Python3 代码实现

def longest_substring_without_repeating_characters(s):left = 0  # 窗口左边界max_length = 0  # 最大长度char_set = set()  # 记录窗口内的字符for right in range(len(s)):while s[right] in char_set:  # 如果字符重复,移动左边界char_set.remove(s[left])left += 1char_set.add(s[right])  # 将当前字符加入集合max_length = max(max_length, right - left + 1)  # 更新最大长度return max_length# 示例
s = "abcabcbb"
print("最长无重复字符子串的长度:", longest_substring_without_repeating_characters(s))

F、总结

通过滑动窗口算法,我们可以高效地找到最长的无重复字符子串。滑动窗口的核心是双指针和动态调整窗口,适合解决连续区间问题。希望这个示例和图解对你有帮助!

© 著作权归作者所有

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/69877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker安装mongo,导入、导出数据

1、docker安装mongo docker pull mongo docker run -d -p 27017:27017 --name mongodb mongodocker update mongodb --restartalways ## 开机自启动-d:表示以后台模式运行容器。 -p 27017:27017:将容器内部的 MongoDB 默认端口 27017 映射到宿主机的 27…

GB300加速推进,RTX 50显卡芯片量产延后,NVIDIA面临新的挑战与机遇

野村分析师Anne Lee在2月12日的报告中表示,2025年全球服务器营收将同比增长46%,2026年增长22%。其中,AI服务器营收预计在2025年和2026年分别增长75%和31%。这些预测与近期美国主要云服务提供商(CSP)上调的资本支出指引基本一致。 GB300加速推…

[NOIP2011 普及组] 统计单词数 题解

(一)读懂题目 关键词:查找单词 方法:枚举(二)分析算法时间复杂度和空间复杂度 算法:枚举 时间复杂度:O(n) 空间复杂度:O(n)(三)代码实现 代码如…

深入解析 ipoib_intf_init 函数中的 netdev_ops 设置逻辑

在 Linux 内核的网络设备驱动开发中,net_device_ops 是一个至关重要的结构体,它定义了网络设备的各种操作函数指针,决定了网络设备的行为和功能。本文将深入解析 ipoib_intf_init 函数中关于 dev->netdev_ops 和 priv->rn_ops 的设置逻辑,帮助读者理解其设计动机和实…

leetcode_1760 袋子里最少数目的球

1. 题意 给定一个数组,和一个最多次操作次数。每次操作可以将数组中的一个数 x x x分成两个数 t x − t t\quad x-t tx−t。问 m a x O p e r a t i o n C n t maxOperationCnt maxOperationCnt次操作后,数组中最大的数最小的值是多少。 2. 题解 这个…

TDengine 性能测试工具 taosBenchmark

简介工具获取运行 无参数模式命令行模式配置文件模式 命令行参数配置文件参数 通用配置参数写入配置参数 数据库相关超级表相关标签列与数据列写入行为相关 查询配置参数 执行指定查询语句查询超级表 订阅配置参数数据类型对照表 配置文件示例 写入 JSON 示例查询 JSON 示例订阅…

J6 X8B/X3C切换HDR各帧图像

1、OV手册上的切换命令 寄存器为Ox5074 各帧切换: 2、地平线control tool实现切换命令 默认HDR模式出图: HCG出图: LCG出图 SPD出图 VS出图

游戏引擎学习第101天

回顾当前情况 昨天的进度基本上完成了所有内容,但我们还没有进行调试。虽然我们在运行时做的事情大致上是对的,但还是存在一些可能或者确定的bug。正如昨天最后提到的,既然现在时间晚了,就不太适合开始调试,所以今天我…

【故障处理】- RMAN-06593: platform name ‘Linux x86 64-bitElapsed: 00:00:00.00‘

【故障处理】- RMAN-06593: platform name Linux x86 64-bitElapsed: 00:00:00.00 一、概述二、报错原因三、解决方法 一、概述 使用xtts迁移,在目标端进行恢复时,遇到RMAN-06593: platform name Linux x86 64-bitElapsed: 00:00:00.00’报错。 二、报错…

多模态本地部署和ollama部署Llama-Vision实现视觉问答

文章目录 一、模型介绍二、预期用途1. 视觉问答(VQA)与视觉推理2. 文档视觉问答(DocVQA)3. 图像字幕4. 图像-文本检索5. 视觉接地 三、本地部署1. 下载模型2. 模型大小3. 运行代码 四、ollama部署1. 安装ollama2. 安装 Llama 3.2 Vision 模型3. 运行 Llama 3.2-Vision 五、效果…

哪吒闹海!SCI算法+分解组合+四模型原创对比首发!SGMD-FATA-Transformer-LSTM多变量时序预测

哪吒闹海!SCI算法分解组合四模型原创对比首发!SGMD-FATA-Transformer-LSTM多变量时序预测 目录 哪吒闹海!SCI算法分解组合四模型原创对比首发!SGMD-FATA-Transformer-LSTM多变量时序预测效果一览基本介绍程序设计参考资料 效果一览…

MySQL调用存储过程和存储函数

【图书推荐】《MySQL 9从入门到性能优化(视频教学版)》-CSDN博客 《MySQL 9从入门到性能优化(视频教学版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

TCP粘包/拆包

一、什么是 TCP 粘包/拆包?发生的原因?怎么解决? TCP粘包:指在进行TCP数据传输时,多个小的数据包被合并成一个大的数据包进行传输的现象。 TCP拆包:指一个大的数据包被拆分成多个小的数据包进行传输的现象…

网络防御高级-第8章及之前综合作业

标准版 接口ip配置 r2 [r2]interface GigabitEthernet 0/0/0 [r2-GigabitEthernet0/0/0]ip address 13.0.0.3 24 [r2-GigabitEthernet0/0/0]interface GigabitEthernet 0/0/1 [r2-GigabitEthernet0/0/1]ip address 100.1.1.254 24 [r2-GigabitEthernet0/0/1]interface Gigab…

常见的排序算法:插入排序、选择排序、冒泡排序、快速排序

1、插入排序 步骤: 1.从第一个元素开始,该元素可以认为已经被排序 2.取下一个元素tem,从已排序的元素序列从后往前扫描 3.如果该元素大于tem,则将该元素移到下一位 4.重复步骤3,直到找到已排序元素中小于等于tem的元素…

【数据结构】寻找规律:算对角线长度||杨辉三角||魔方问题(C语言实现)

目录标题 三个算法1. 求矩阵对角线元素之和(C语言)2. 杨辉三角3. 幻方问题 总结:都是通过寻找规律来找出构造逻辑然后用循环来实现 三个算法 1. 求矩阵对角线元素之和(C语言) 1.初始化行循环变量i和列循环遍历j&…

Vue的学习(5)

1.路由进阶 1.路由模块封装 路由的封装抽离 问题:所有的路由配置都堆在main.js中合适么? 目标:将路由模块抽离出来。 好处:拆分模块,利于维护 小结: 路由模块的封装抽离的好处是什么? 拆分模…

设备智能化无线通信,ESP32-C2物联网方案,小尺寸芯片实现大功能

在科技飞速发展的当下,我们的生活正被各类智能设备悄然改变,它们如同一位位无声的助手,渗透到我们生活的每一个角落,让生活变得更加便捷和丰富多彩。 智能插座、智能照明和简单家电设备在家居领域的应用,为我们的生活…

python利用jenkins模块操作jenkins

安装python-jenkins 可以使用pip命令来安装python-jenkins模块: pip install python-jenkins操作jenkins 接下来就是连接和操作jenkins,写了个class,直接上代码 class Jenkins():def __init__(self, url, username, password):# jenkins服…

Excel大数据量导入导出

github源码 地址(更详细) : https://github.com/alibaba/easyexcel 文档:读Excel(文档已经迁移) B 站视频 : https://www.bilibili.com/video/BV1Ff4y1U7Qc 一、JAVA解析EXCEL工具EasyExcel Java解析、生成Excel比较…