滑动窗口讲解(c基础)

  1. 滑动窗口的基本概念

滑动窗口是一种高效处理线性数据结构(如数组、字符串)的算法技巧。它就像是一个可移动的 “框”,框住数据结构中的一部分元素,通过不断地移动这个 “框”(即滑动窗口),对框内的元素进行分析和处理,以解决各种与子序列、子数组相关的问题。

  1. 滑动窗口的组成部分

  • 窗口边界
    • 通常由两个指针来定义窗口的边界,例如leftrightleft指针指向窗口的左边界(起始位置),right指针指向窗口的右边界(结束位置)。通过移动这两个指针,可以控制窗口的大小和位置。
  • 窗口大小
    • 可以是固定大小,也可以是根据特定规则动态变化的。在固定大小的滑动窗口中,窗口大小在整个算法过程中保持不变;而在动态大小的滑动窗口中,窗口大小会根据问题的要求和窗口内元素的性质进行调整。
  • 窗口内容
    • 即窗口边界所包含的元素集合。对这些元素可以进行各种操作,如求和、计数、检查是否满足某种条件等。

  1. 滑动窗口的操作步骤(以一般情况为例)

  • 初始化窗口

    • 首先要确定窗口的初始位置和大小。这可能涉及到将leftright指针初始化为合适的位置,以及初始化一些用于记录窗口相关信息的变量,如窗口内元素的和、计数等。
    • 例如,在固定大小滑动窗口求数组中固定长度子数组的最大和的问题中,初始窗口的和是通过一个循环计算前k个元素的和得到的,此时left = 0right = k - 1
  • 滑动窗口

    • 扩展窗口(右移right指针)
      • 通常,在窗口尚未完全遍历数据结构时,需要不断地向右移动right指针来扩大窗口。在这个过程中,需要更新窗口内元素的相关信息,如将新进入窗口的元素计入总和、计数等操作。
      • 例如,在寻找包含特定字符集合的最小子串的问题中,当right指针右移时,要将新进入窗口的字符在窗口字符计数数组中的计数加 1,并检查是否满足包含所有目标字符的条件。
    • 收缩窗口(左移left指针)
      • 当窗口满足某些条件(如已经包含了足够的元素、达到了某个阈值等)时,可能需要收缩窗口,即左移left指针。在左移过程中,要相应地更新窗口内元素的信息,如将移出窗口的元素从总和、计数中减去。
      • 例如,在最小覆盖子串问题中,当窗口已经包含了目标字符串中的所有字符时,尝试左移left指针来缩小窗口,同时更新窗口状态,直到窗口不再满足包含所有目标字符的条件为止。
  • 更新结果(根据问题要求)

    • 在窗口滑动的过程中,根据问题的具体要求,可能需要不断地更新结果。例如,在求子数组最大和的问题中,每次更新窗口和后,需要比较当前窗口和与最大和,若当前窗口和更大,则更新最大和;在求最小覆盖子串的问题中,每次收缩窗口时,需要比较当前窗口长度与最小窗口长度,若当前窗口长度更小且满足条件,则更新最小窗口长度和起始位置。
  • 终止条件

    • 滑动窗口的操作会在满足一定条件时停止。最常见的情况是right指针到达数据结构的末尾。例如,在遍历完整个数组或者字符串后,滑动窗口的过程结束。

  1. 示例 - 固定大小滑动窗口(求数组中固定长度子数组的最大和)详细讲解

  • 代码回顾
    • 展开过程

收起

plaintext

复制

- **初始化窗口(第1 - 7行)**:
    - 首先,函数检查数组`nums`的大小`numsSize`是否小于给定的子数组长度`k`。如果是,那么不存在长度为`k`的子数组,直接返回0。
    - 接着,通过一个循环(第4 - 6行)计算初始窗口(前`k`个元素)的和,将其存储在`window_sum`变量中。同时,将`max_sum`也初始化为这个窗口和的值,因为此时它是目前找到的最大和(因为还没有开始滑动窗口)。
- **滑动窗口(第8 - 13行)**:
    - 从第`k`个元素开始(索引为`k - 1`),进入`for`循环(第8 - 13行),这个循环控制窗口的滑动。在每次循环中,通过`window_sum = window_sum - nums[i - k] + nums[i]`来更新窗口内元素的和。
    - 具体来说,`window_sum - nums[i - k]`这部分是减去窗口最左边滑出的元素(因为窗口向右滑动了一个位置,最左边的元素就离开了窗口)。例如,当`i = k`时,`nums[i - k]`就是初始窗口的第一个元素`nums[0]`。然后`+ nums[i]`这部分是添加新进入窗口的元素,此时`nums[i]`就是窗口向右滑动一个位置后新进入窗口的元素。
- **更新结果(第11 - 12行)**:
    - 在每次更新窗口和之后,比较`window_sum`和`max_sum`的大小。如果`window_sum`大于`max_sum`,就将`max_sum`更新为`window_sum`。这样,在整个窗口滑动过程中,`max_sum`始终记录着到目前为止长度为`k`的子数组的最大和。
- **终止条件(第8行循环条件)**:
    - 循环条件是`i < numsSize`,这意味着只要窗口的右端点(`right`指针对应的位置,即`i`)还没有超出数组的范围,窗口就会持续向右滑动。当`right`指针到达数组末尾时,循环结束,此时`max_sum`中存储的就是数组中长度为`k`的子数组的最大和,最后将其返回。

5. **示例 - 动态大小滑动窗口(寻找包含特定字符集合的最小子串)详细讲解**

- **代码回顾(简化部分初始化代码)**:
    - ```c
      char *min_window(char *s, char *t) {
          int need[128] = {0};
          int window[128] = {0};
          int left = 0, right = 0;
          int match_count = 0;
          int min_len = strlen(s) + 1;
          int min_left = 0;
          // 统计t中字符出现的次数
          for (int i = 0; i < strlen(t); i++) {
              need[t[i]]++;
          }
          while (right < strlen(s)) {
              window[s[right]]++;
              if (window[s[right]] == need[s[right]]) {
                  match_count++;
              }
              while (match_count == strlen(t)) {
                  if (right - left + 1 < min_len) {
                      min_len = right - left + 1;
                      min_left = left;
                  }
                  window[s[left]]--;
                  if (window[s[left]] < need[s[left]] {
                      match_count--;
                  }
                  left++;
              }
              right++;
          }
          if (min_len <= strlen(s)) {
              char *result = (char *)malloc((min_len + 1) * sizeof(char));
              strncpy(result, s + min_left, min_len);
              result[min_len] = '\0';
              return result;
          } else {
              return "";
          }
      }

  • 初始化窗口(第 1 - 7 行和第 10 - 11 行)
    • 定义了两个数组needwindow,分别用于记录目标字符串t中字符出现的次数和滑动窗口内字符出现的次数。这两个数组的大小为 128,足以覆盖 ASCII 码表中的常见字符。
    • 初始化了窗口边界指针leftright为 0,表示窗口初始位置在字符串s的开头。同时初始化了match_count为 0,用于记录窗口内已经匹配上t中字符的个数;min_lenstrlen(s) + 1,用于记录最小子串的长度,初始值设为一个较大的值;min_left为 0,用于记录最小子串的起始位置。
    • 通过一个循环(第 10 - 11 行)统计字符串t中字符出现的次数,存储在need数组中。
  • 滑动窗口(第 12 - 22 行)
    • 扩展窗口(第 13 - 15 行)
      • 在主while循环(第 12 - 22 行)中,首先不断右移right指针(第 17 行)来扩大窗口。每次将新进入窗口的字符在window数组中的计数加 1(第 14 行)。
      • 然后检查窗口内该字符的计数是否等于need数组中该字符的计数,如果是,则将match_count加 1(第 15 行),表示又匹配上了一个t中的字符。
    • 收缩窗口(第 16 - 21 行)
      • match_count等于t的长度时,说明窗口内已经包含了t中所有的字符,此时进入内层while循环(第 16 - 21 行)开始收缩窗口。
      • 在收缩窗口过程中,首先检查当前窗口长度(right - left + 1)是否小于min_len,如果是,则更新min_lenmin_left(第 18 - 19 行),记录下当前更小的子串。
      • 接着,将窗口左边界left指向的字符在window数组中的计数减 1(第 20 行)。如果此时窗口内该字符的计数小于need数组中该字符的计数,那么match_count减 1(第 21 行),表示窗口不再包含t中所有的字符,停止收缩窗口。
  • 更新结果(第 18 - 19 行)
    • 在收缩窗口阶段,当窗口长度变小且仍然满足包含所有目标字符的条件时,更新min_lenmin_left,这两个变量始终记录着到目前为止找到的最小子串的长度和起始位置。
  • 终止条件(第 12 行循环条件)
    • 外层while循环的条件是right < strlen(s),这意味着只要窗口的右端点(right指针对应的位置)还没有超出字符串s的范围,窗口就会持续滑动。当right指针到达字符串末尾时,循环结束。
  • 返回结果(第 23 - 28 行)
    • 最后,根据min_len的值来返回结果。如果min_len小于等于s的长度,说明找到了满足条件的最小子串,通过malloc分配足够的内存来存储这个子串,使用strncpy函数将子串复制到新分配的内存中,并添加字符串结束符'\0',然后返回这个结果。如果min_len大于s的长度,说明没有找到满足条件的子串,返回空字符串。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DRM(数字权限管理技术)防截屏录屏----ffmpeg安装

提示&#xff1a;ffmpeg安装 文章目录 [TOC](文章目录) 前言一、下载二、配置环境变量三、运行ffmpeg四、文档总结 前言 FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的…

github webhooks 实现网站自动更新

本文目录 Github Webhooks 介绍Webhooks 工作原理配置与验证应用云服务器通过 Webhook 自动部署网站实现复制私钥编写 webhook 接口Github 仓库配置 webhook以服务的形式运行 app.py Github Webhooks 介绍 Webhooks是GitHub提供的一种通知方式&#xff0c;当GitHub上发生特定事…

全桥LLC变换器原理及MATLAB仿真模型

“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 主电路拓扑 全桥LLC 谐振变换器主电路拓扑结构图。图中S1 &#xff5e; S4为功率开关管&#xff0c; D1 &#xff5e; D4为功率开关管的体二极管&#xff0c; C1 &#xff5e; C4 为功率开关管的寄生电容。谐振电感r…

使用R语言进行美国失业率时空分析(包括绘图)

今天写一篇利用R语言&#xff0c;针对面板数据的简单分析与绘图。让我们直接开始把。 一、数据准备 这次的示例数据非常简单&#xff0c;只有一个shp格式的美国区县矢量数据&#xff0c;我们在QGIS中打开数据查看一下它的属性表。事实上我们需要的数据都在属性表的字段中。 二…

PostgreSQL在Linux环境下的常用命令总结

标题 登录PgSQL库表基本操作命令新建库表修改库表修改数据库名称&#xff1a;修改表名称修改表字段信息 删除库表pgsql删除正在使用的数据库 须知&#xff1a; 以下所有命令我都在Linux环境中执行验证过&#xff0c;大家放心食用&#xff0c;其中的实际名称换成自己的实际名称即…

React Native学习笔记(三)

一 组件简介 1.1 简介 RN中的核心组件&#xff0c;是对原生组件的封装 原生组件&#xff1a;Android或ios内的组件核心组件&#xff1a;RN中常用的&#xff0c;来自react-native的组件 原生组件 在 Android 开发中是使用 Kotlin 或 Java 来编写视图&#xff1b;在 iOS 开发…

TsingtaoAI具身智能高校实训方案通过华为昇腾技术认证

日前&#xff0c;TsingtaoAI推出的“具身智能高校实训解决方案-从AI大模型机器人到通用具身智能”基于华为技术有限公司AI框架昇思MindSpore&#xff0c;完成并通过昇腾相互兼容性技术认证。 TsingtaoAI&华为昇腾联合解决方案 本项目“具身智能高校实训解决方案”以实现高…

基于matlab程序实现人脸识别

1.人脸识别流程 1.1.1基本原理 基于YCbCr颜色空间的肤色模型进行肤色分割。在YCbCr色彩空间内对肤色进行了建模发现&#xff0c;肤色聚类区域在Cb—Cr子平面上的投影将缩减&#xff0c;与中心区域显著不同。采用这种方法的图像分割已经能够较为精确的将人脸和非人脸分割开来。…

SQL Server管理员sa登录失败原因

文章目录 一、开启混合登录模式二、启用sa三、更改密码四、登录sa一、开启混合登录模式 用Windows身份登录数据库服务。 在连接名上右键→属性。 在安全性选项卡下,选择【SQL Server和Windows身份验证模式】,点击【确定】,提示需要重启服务。 Win+R,输入指令:services.ms…

15分钟做完一个小程序,腾讯这个工具有点东西

我记得很久之前&#xff0c;我们都在讲什么低代码/无代码平台&#xff0c;这个概念很久了&#xff0c;但是&#xff0c;一直没有很好的落地&#xff0c;整体的效果也不算好。 自从去年 ChatGPT 这类大模型大火以来&#xff0c;各大科技公司也都推出了很多 AI 代码助手&#xff…

探秘多源异构数据:开启数据融合新时代

多源异构数据&#xff0c;其 “多源” 体现了数据来源的广泛多样性。在当今数字化时代&#xff0c;数据可能来自于不同的系统&#xff0c;比如企业内部可能同时使用多种管理系统&#xff0c;如 ERP&#xff08;企业资源计划&#xff09;系统、CRM&#xff08;客户关系管理&…

R语言结构方程模型(SEM)在生态学领域中的应用

目录 专题一、R/Rstudio简介及入门 专题二、结构方程模型&#xff08;SEM&#xff09;介绍 专题三&#xff1a;R语言SEM分析入门&#xff1a;lavaan VS piecewiseSEM 专题四&#xff1a;SEM全局估计&#xff08;lavaan&#xff09;在生态学领域高阶应用 专题五&#xff1…

springboot中使用mongodb完成评论功能

pom文件中引入 <!-- mongodb --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> yml中配置连接 data:mongodb:uri: mongodb://admin:1234561…

K8S版本和istio版本的对照关系

版本对照关系 下载地址1 下载地址2

Milvus×Florence:一文读懂如何构建多任务视觉模型

近两年来多任务学习&#xff08;Multi-task learning&#xff09;正取代传统的单任务学习&#xff08;single-task learning&#xff09;&#xff0c;逐渐成为人工智能领域的主流研究方向。其原因在于&#xff0c;多任务学习可以让我们以最少的人力投入&#xff0c;获得尽可能多…

课题组自主发展了哪些CMAQ模式预报相关的改进技术?

空气污染问题日益受到各级政府以及社会公众的高度重视&#xff0c;从实时的数据监测公布到空气质量数值预报及预报产品的发布&#xff0c;我国在空气质量监测和预报方面取得了一定进展。随着计算机技术的高速发展、空气污染监测手段的提高和人们对大气物理化学过程认识的深入&a…

CAD 文件 批量转为PDF或批量打印

CAD 文件 批量转为PDF或批量打印&#xff0c;还是比较稳定的 1.需要本地安装CAD软件 2.通过 Everything 搜索工具搜索&#xff0c;DWG To PDF.pc3 &#xff0c;获取到文件目录 &#xff0c;替换到代码中&#xff0c; originalValue ACADPref.PrinterConfigPath \ r"C:…

家校通小程序实战教程04教师管理

目录 1 创建数据源2 搭建管理后台3 搭建查询条件4 功能测试总结 我们上一篇介绍了如何将学生加入班级&#xff0c;学生加入之后就需要教师加入了。教师分为任课老师和班主任&#xff0c;班主任相当于一个班级的管理员&#xff0c;日常可以发布各种任务&#xff0c;发布接龙&…

即时通讯| IM+RTC在AI技术加持下的社交体验

即时通讯作为互联网的重要应用之一&#xff0c;见证了中国互联网30年发展的辉煌历程。 它从最初的文字交流&#xff0c;发展到如今的语音、视频通话&#xff0c;甚至是虚拟现实社交&#xff0c;已经渗透到生活的社交、娱乐、商务等方方面面&#xff0c;成为现代社会不可或缺的一…

基于 Spring Boot 实现图片的服务器本地存储及前端回显

&#x1f3af;导读&#xff1a;本文探讨了在网站开发中图片存储的各种方法&#xff0c;包括本地文件系统存储、对象存储服务&#xff08;如阿里云OSS&#xff09;、数据库存储、分布式文件系统及内容分发网络&#xff08;CDN&#xff09;。文中详细对比了这些方法的优缺点&…