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

算法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 += 1
        char_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、总结

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

© 著作权归作者所有

相关文章:

  • GitHub推荐C++项目:基于muduo、protobuf、zookeeper实现RPC框架
  • HTML之JavaScript使用JSON
  • 尚硅谷爬虫note006
  • 什么是HTTP Error 429以及如何修复
  • Reinforcement Learning Heats Up 强化学习持续升温
  • PHP下载安装以及基本配置
  • java八股---java基础04(集合、异常、引用、线程)
  • DeepSeek本地化部署【window下安装】【linux下安装】
  • 如何使用DeepSeek学习新技能?
  • Redis 数据类型 List 列表
  • 消息队列之-RabbitMq 学习
  • 无人机遥感图像拼接及处理实践技术:生态环境监测、农业、林业等领域,结合图像拼接与处理技术,能够帮助我们更高效地进行地表空间要素的动态监测与分析
  • MySQL 篇 - Java 连接 MySQL 数据库并实现数据交互
  • 【观测先锋·制造业卓越可观测建设案例】 中顺洁柔—基于Bonree ONE实现AI大模型高级一体化可观测运维监控解决方案
  • QT设备树,具有设备树过滤功能
  • 什么是计算机中的 “终端”?
  • LeetCode《算法通关手册》 1.2 数组排序
  • 基于springboot+vue的考研学习分享平台设计与实现
  • 最新华为 HCIP-Datacom(H12-821)
  • Cisco Fabric Manager 5.0:统一数据的可见性和控制
  • 被围观的“英之园”,谁建了潮汕天价违建?
  • 小米汽车回应部分SU7前保险杠形变
  • 张巍任中共河南省委副书记
  • 征稿启事|澎湃·镜相第三届非虚构写作大赛暨2026第六届七猫现实题材征文大赛
  • 中国科学院院士、我国航天液体火箭技术专家朱森元逝世
  • 光明日报:家长孩子共同“息屏”,也要保证高质量陪伴