滑动窗口算法详解:从入门到精通

news2025/3/18 7:16:55

目录

引言

1. 滑动窗口算法简介

2. 滑动窗口的基本思想

3. 滑动窗口的应用场景

3.1 最大子数组和

3.2 最小覆盖子串

3.3 最长无重复字符子串

4. 滑动窗口的实现步骤

5. 滑动窗口的代码示例

6. 滑动窗口的优化技巧

6.1 使用哈希表记录字符频率

6.2 使用双指针维护窗口

6.3 提前终止遍历

7. 总结


引言

滑动窗口算法(Sliding Window Algorithm)是一种在数组或字符串上进行高效操作的技巧。它通过维护一个窗口(通常是一个子数组或子字符串),在遍历过程中动态调整窗口的起始和结束位置,从而避免重复计算,提升算法效率。滑动窗口算法广泛应用于解决子数组、子字符串相关的问题,如最大子数组和、最小覆盖子串、最长无重复字符子串等。

本文将深入探讨滑动窗口算法的原理、应用场景以及实现细节,帮助读者从入门到精通掌握这一重要算法。

1. 滑动窗口算法简介

滑动窗口算法是一种通过维护一个窗口来解决问题的技巧。窗口通常是一个连续的子数组或子字符串,算法的核心思想是通过调整窗口的起始和结束位置,来高效地找到满足条件的解。

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

  • 寻找满足条件的子数组或子字符串

  • 计算子数组或子字符串的最值

  • 统计满足条件的子数组或子字符串的数量

2. 滑动窗口的基本思想

滑动窗口算法的基本思想是通过两个指针(通常是左指针和右指针)来维护一个窗口。窗口的起始位置由左指针决定,结束位置由右指针决定。在遍历过程中,右指针不断向右移动,扩大窗口,直到窗口中的元素满足某个条件;然后左指针开始向右移动,缩小窗口,直到窗口中的元素不再满足条件。通过这种方式,可以在一次遍历中找到所有满足条件的子数组或子字符串。

滑动窗口算法的关键在于如何高效地调整窗口的大小,以及如何在窗口调整过程中维护所需的信息(如窗口中的元素和、最大值、最小值等)。

3. 滑动窗口的应用场景

滑动窗口算法广泛应用于各种算法问题中,以下是一些常见的应用场景:

3.1 最大子数组和

给定一个整数数组,找到一个具有最大和的连续子数组。滑动窗口算法可以通过维护一个窗口来计算当前子数组的和,并在遍历过程中不断更新最大和。

3.2 最小覆盖子串

给定一个字符串 S 和一个字符串 T,在 S 中找到包含 T 所有字符的最短子串。滑动窗口算法可以通过维护一个窗口来统计窗口中的字符频率,并在遍历过程中调整窗口的大小,找到满足条件的最短子串。

3.3 最长无重复字符子串

给定一个字符串,找到其中最长的没有重复字符的子串。滑动窗口算法可以通过维护一个窗口来记录窗口中的字符,并在遍历过程中调整窗口的大小,找到最长的无重复字符子串。

4. 滑动窗口的实现步骤

滑动窗口算法的实现通常包括以下几个步骤:

  1. 初始化窗口:设置左指针和右指针的初始位置,通常左指针和右指针都指向数组或字符串的起始位置。

  2. 扩展窗口:右指针向右移动,扩大窗口,直到窗口中的元素满足某个条件。

  3. 收缩窗口:左指针向右移动,缩小窗口,直到窗口中的元素不再满足条件。

  4. 更新结果:在窗口调整过程中,根据问题的要求更新结果(如最大和、最小长度等)。

  5. 重复步骤2-4:继续遍历数组或字符串,直到右指针到达末尾。

5. 滑动窗口的代码示例

以下是一个使用滑动窗口算法解决“最长无重复字符子串”问题的代码示例:

def length_of_longest_substring(s: str) -> int:
    # 使用字典记录字符最后出现的位置
    char_index_map = {}
    max_length = 0
    left = 0
    
    for right in range(len(s)):
        if s[right] in char_index_map:
            # 如果字符已经出现过,更新左指针
            left = max(left, char_index_map[s[right]] + 1)
        # 更新字符最后出现的位置
        char_index_map[s[right]] = right
        # 更新最大长度
        max_length = max(max_length, right - left + 1)
    
    return max_length

# 测试用例
s = "abcabcbb"
print(length_of_longest_substring(s))  # 输出: 3

在这个示例中,我们使用一个字典 char_index_map 来记录每个字符最后出现的位置。通过维护一个窗口(由 left 和 right 指针定义),我们可以在遍历过程中动态调整窗口的大小,找到最长的无重复字符子串。

6. 滑动窗口的优化技巧

滑动窗口算法的效率取决于如何高效地调整窗口的大小以及如何在窗口调整过程中维护所需的信息。以下是一些优化滑动窗口算法的技巧:

6.1 使用哈希表记录字符频率

在处理字符串相关的问题时,可以使用哈希表来记录窗口中的字符频率。这样可以快速判断窗口中的字符是否满足条件,从而高效地调整窗口的大小。

6.2 使用双指针维护窗口

滑动窗口算法通常使用双指针(左指针和右指针)来维护窗口。通过合理地移动双指针,可以在一次遍历中完成所有操作,避免重复计算。

6.3 提前终止遍历

在某些情况下,可以在遍历过程中提前终止算法。例如,在寻找最小覆盖子串时,如果当前窗口已经是最小的可能窗口,可以提前终止遍历。

7. 总结

滑动窗口算法是一种高效解决子数组、子字符串相关问题的技巧。通过维护一个窗口,并在遍历过程中动态调整窗口的大小,滑动窗口算法可以在一次遍历中找到满足条件的解,避免了重复计算,提升了算法效率。

掌握滑动窗口算法的关键在于理解其基本思想,熟悉常见的应用场景,并能够灵活运用各种优化技巧。希望通过本文的讲解,读者能够从入门到精通掌握滑动窗口算法,并在实际编程中灵活运用。


参考文章

  1. LeetCode 滑动窗口问题集

  2. 滑动窗口算法详解

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

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

相关文章

[贪心算法]-最大数(lambda 表达式的补充)

1.解析 我们一般使用的排序比较大小都是 a>b 那么a在b的前面 ab 无所谓 a<b a在b的后面 本题的排序则是 ab>ba 那么a在b的前面 abba 无所谓 ab<ba a在b的后面 2.代码 class Solution { public:string largestNumber(vector<int>& nums) {//1.先把所有…

C语言 —— 此去经年梦浪荡魂音 - 深入理解指针(卷二)

目录 1. 数组名与地址 2. 指针访问数组 3.一维数组传参本质 4.二级指针 5. 指针数组 6. 指针数组模拟二维数组 1. 数组名与地址 我们先看下面这个代码&#xff1a; int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* p &arr[0]; 这里我们使用 &arr[0] 的方式拿到了数…

python实现简单的图片去水印工具

python实现简单的图片去水印工具 使用说明&#xff1a; 点击"打开图片"选择需要处理的图片 在图片上拖拽鼠标选择水印区域&#xff08;红色矩形框&#xff09; 点击"去除水印"执行处理 点击"保存结果"保存处理后的图片 运行效果 先简要说明…

使用dify+deepseek部署本地知识库

使用difydeepseek部署本地知识库 一、概述二、安装windows docker desktop1、确认系统的Hyper-v功能正常启用2、docker官网下载安装windows客户端3、安装完成后的界面如下所示 三、下载安装ollama四、部署本地deepseek五、本地下载部署dify5.1 下载dify的安装包5.2 将dify解压到…

【算法day13】最长公共前缀

最长公共前缀 https://leetcode.cn/problems/longest-common-prefix/submissions/612055945/ 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 class Solution { public:string longestCommonPrefix(vector<string&g…

Java高频面试之集合-13

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;为什么 hash 函数能降哈希碰撞&#xff1f; 哈希函数通过以下核心机制有效降低碰撞概率&#xff0c;确保不同输入尽可能映…

RGV调度算法(三)--遗传算法

1、基于时间窗 https://wenku.baidu.com/view/470e9fd8b4360b4c2e3f5727a5e9856a57122693.html?_wkts_1741880736197&bdQuery%E7%8E%AF%E7%A9%BF%E8%B0%83%E5%BA%A6%E7%AE%97%E6%B3%95 2.2019年MathorCup高校数学建模挑战赛B题 2019-mathorcupB题-环形穿梭机调度模型&a…

YOLOv8轻量化改进——Coordinate Attention注意力机制

现在针对YOLOv8的架构改进越来越多&#xff0c;今天尝试引入了Coordinate Attention注意力机制以改进对小目标物体的检测效率。 yolov8的下载和安装参考我这篇博客&#xff1a; 基于SeaShips数据集的yolov8训练教程_seaships处理成yolov8-CSDN博客 首先我们可以去官网找到CA注…

基于SpringBoot+Vue的驾校预约管理系统+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、普通用户、教练功能模块&#xff1a;用户管理、管理员管理、教练管理、教练预约管理、车辆管理、车辆预约管理、论坛管理、基础数据管理等技术选型&#xff1a;SpringBoot&#xff0c;Vue等测试环境&#xff1a;idea2024&#xff0c;j…

ONNX:统一深度学习工作流的关键枢纽

引言 在深度学习领域&#xff0c;模型创建与部署的割裂曾是核心挑战。不同框架训练的模型难以在多样环境部署&#xff0c;而 ONNX&#xff08;Open Neural Network Exchange&#xff09;作为开放式神经网络交换格式&#xff0c;搭建起从模型创建到部署的统一桥梁&#xff0c;完…

蓝桥杯————23年省赛 ——————平方差

3.平方差 - 蓝桥云课 一开始看题我还没有意识到问题的严重性 我丢&#xff0c;我想 的是用两层循环来做&#xff0c;后来我试了一下最坏情况&#xff0c;也就是l1 r 1000000000 结果运行半天没运行出来&#xff0c;我就知道坏了&#xff0c;孩子们&#xff0c;要出事&#…

一、串行通信基础知识

一、串行通信基础知识 1.处理器与外部设备通信有两种方式 并行通信&#xff1a;数据的各个位用多条数据线同时传输。&#xff08;传输速度快&#xff0c;但占用引脚资源多。&#xff09; 串行通信&#xff1a;将数据分成一位一位的形式在一条数据线上逐个传输。&#xff08;线路…

自带多个接口,完全免费使用!

做自媒体的小伙伴们&#xff0c;是不是经常为语音转文字的事儿头疼&#xff1f; 今天给大家推荐一款超实用的语音转文字软件——AsrTools&#xff0c;它绝对是你的得力助手&#xff01; AsrTools 免费的语音转文字软件 这款软件特别贴心&#xff0c;完全免费&#xff0c;而且操…

Qt QML解决SVG图片显示模糊的问题

前言 在QML中直接使用SVG图片&#xff0c;使用Image控件加载资源&#xff0c;显示出来图片是模糊的&#xff0c;很影响使用体验。本文介绍重新绘制SVG图片&#xff0c;然后注册到QML中使用。 效果图&#xff1a; 左边是直接使用Image加载资源显示的效果 右边是重绘后的效果 …

【Linux我做主】基础命令完全指南上篇

Linux基础命令完全指南【上篇】 Linux基础命令完全指南github地址前言命令行操作的引入Linux文件系统树形结构的根文件系统绝对路径和相对路径适用场景Linux目录下的隐藏文件 基本指令目录和文件相关1. ls2. cd和pwdcdpwd 3. touch4. mkdir5. cp6. mv移动目录时覆盖写入的两种特…

Designing Dashboards with SAP Analytics Cloud

Designing Dashboards with SAP Analytics Cloud

项目实战系列:基于瑞萨RA6M5构建多节点OTA升级-系统设计<一>

项目背景 原嵌入式控制系统采用分布式模块化架构&#xff0c;由12个功能板卡&#xff08;通信控制、信号采集、驱动执行等&#xff09;组成。系统维护阶段存在以下痛点&#xff1a; 低效的本地烧录机制&#xff1a;各板卡固件升级需通过JTAG接口逐一手动连接JLINK仿真器&#x…

《AI大模型趣味实战》 No3:快速搭建一个漂亮的AI家庭网站-相册/时间线/日历/多用户/个性化配色/博客/聊天室/AI管家(下)

《AI大模型趣味实战》 No3&#xff1a;快速搭建一个漂亮的AI家庭网站-相册/时间线/日历/多用户/个性化配色/博客/聊天室/AI管家(下) 摘要 本文介绍了家庭网站V1.3版本的更新内容&#xff0c;主要聚焦于AI管家功能的优化与完善。V1.3版本对AI管家模块进行了全面升级&#xff0…

c++基础知识-图论进阶

一、拓扑排序 1、基础知识 1&#xff09;什么是拓扑排序 对一个有向无环图G进行拓扑排序&#xff0c;是将G中所有顶点排成一个线性序列&#xff0c;使得图中任意一对顶点u和v&#xff0c;若&#xff0c;则u在线性序列中出现在v之前。 2&#xff09;拓扑排序的操作方法 重复执行…