算法通关村第十六关青铜挑战——原来滑动窗口如此简单!

大家好,我是怒码少年小码。

从本篇开始,我们就要开始算法的新篇章了——四大思想:滑动窗口、贪心、回溯、动态规划。现在,向我们迎面走来的是——滑动窗口思想!😝

滑动窗口思想

概念

在数组双指针里,我们介绍过"对撞型"和"快慢型"两种方式,而滑动窗口思想就是快慢型的特例。

实际使用

计算机网络中有滑动窗口协议(Sliding Window Protocol),该协议是TCP实现流量控制等的核心策略之一。事实上与流量控制、熔断、限流、超时等场景下都会首先从滑动窗口的角度思考问题,例如hystrix、sentinel等框架等都使用了这种思想。

理解

这个思想其实很好理解,如下图,假如窗口的大小是3,当不断有新数据来时,我们会维护一个大小为3的一个区间,超过3的就将新的放入老的移走。

这个过程有点像火车在铁轨上跑,原始数据可能保存在一个很大的空间里(铁轨),但是我们标记的小区间就像一列长度固定的火车,一直向前走。

有了区间,就可以造题了,例如让你找序列上三个连续数字的最大和是多少、子数组平均数是多少(LeetCode643)等等。

窗口和滑动的含义:

  1. 窗口:窗口其实就是两个变量leftright之间的元素,也可以理解为一个区间。窗口大小不一定固定,思考两种场景:
  • 如果是固定的,一般要先确定窗口是否越界,再执行逻辑处理。则一般会让你求哪个窗口的元素最大、最小、平均值、和最大、和最小等类型的问题

  • 如果是可变的窗口,一般先判断是否满足要求,再执行逻辑处理。则一般要求一个序列里最大、最小窗口是什么

  1. 滑动:说明这个窗口是移动的,事实上移动的仍然是leftright两个变量,而不是序列中的元素。当变量移动时,其中间的元素必然会发生变化,因此就有这种不断滑动的效果.

注意事项

  1. 解题最终要落实到数组上,特别需要注意边界处理
  2. 有些元素的比较、判断等比较麻烦,要借助集合等工具,而且处理过程中还有一些技巧(常见方法的使用等)
  3. 堆,堆结构非常适合在流数据中找固定区间内的最大、最小等问题。因此滑动窗口经常和堆一起使用可以完美解决很多复杂问题.

那双指针和滑动窗口啥区别呢?

答:根据性质看到,滑动窗口是双指针的一种类型,主要关注两个指针之间元素的情况,范围更小一些,而双指针的应用范围更大,花样也更多。

入门小题

LeetCode 643:给你一个由 n 个元素组成的整数数组 nums 和一个整数 k。请你找出平均数最大且 长度为 k 的连续子数组,并输出该最大平均数。

先自己思考一下,不难但是想要完全做对还是要细心。例如我一开始就是先定义一个变量max保存最大值,然后left和right保存窗口两端。只要right不到数组边界,滑动窗口每次一变我就计算窗口内的元素之和,然后和max比较看看是否保存。

但是我一开始把max定为0,忽略数组内k个最大连续组序列的和是负数的情况。力扣上我又换回C++用INT_MIN来定义结果是直接超时了啊哈哈哈😁。正确代码如下:

public double findMaxAverage(int[] nums, int k) {
    if(k > nums.length || nums.length < 1 || k < 0){
      return 0;
    }
    int len = nums.length;
    int windowSum = 0;
    //先求出第一个窗口内的元素和
    for(int i = 0 ; i < k ;i++){
      windowSum = windowSum + nums[i];
    }
    //然后依次遍历,知道right达到数组边界,每次窗口变化选择变化前后最大的保存
    int maxSum = windowSum;
    for(int right = k ; right < len ; right++){
      windowSum = windowSum + nums[right] - nums[right - k];
      maxSum=Math.max(maxSum,windowSum);
    }
    return (double) maxSum / k;
}

最长连续递增序列

给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。

示例 1:

  • 输入:nums = [1,3,5,4,7]
  • 输出:3
  • 解释:最长连续递增序列是 [1,3,5], 长度为3。
    尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。

示例 2:

  • 输入:nums = [2,2,2,2,2]
  • 输出:1
  • 解释:最长连续递增序列是 [2], 长度为1。

思路:如果当前遍历到的元素比它左边的那一个元素要严格大,right就增加;
否则就将left跳到right的起始位置,重新开始计算。

public int findLengthOfLCIS(int[] nums) {
  int left=0,right=0;
  int res=0;
  while(right < nums.length){
      //右侧的新元素比左侧小,则重新开始记录left的位置
      if(right > 0 && nums[right - 1] >= nums[right]){
          left = right;
      }
      right++;
      res=Math.max(res,right - left);
  }
  return res;
}

本题还有多种解法,另外一种思路是一边遍历,一边统计每个递增区间的长度,如果长度超过之前所有区间的长度,就将其保留,代码如下:

public int findLengthOfLCIS(int[] nums) {
   int curLen = 1;//当前递增区间的长度
   int res = 1;
   for(int i = 1;i < nums.length;i++){
       if(nums[i - 1] >= nums[i]){
           //不满足要求,重新进行数字计算
           curLen = 1;
       }else{
           curLen++;
       }
       res = Math.max(curLen,res);
   }
   return res;
}

可见就算不知道滑动窗口我们也能解决,所以滑动窗口就是个名字,不要被这些概念吓到。

END

本篇只是一个入门,很多时候往往存在即合理,这种思想一定在某个地方发挥着作用,我们下篇探讨!😎再见~

关注微信公众号:怒码少年。回复关键词【电子书】,领取多本计算机相关电子书
公众号后台开启了咨询业务,欢迎大家向我提问,免费,为爱发电😎

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

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

相关文章

SQL使用

--天空会的像哭过&#xff0c;离开你以后 并没有更自由 SQL进行数据的删除 一、删除delete 语法 delete [from] 表名称 where 条件数据删除&#xff0c;不能删除某一列&#xff0c;因为删除是对记录而言 2.1 删除是一条一条删除&#xff0c;每次删除都会将操作写入日志文件 删…

记录第一次利用CVE-2023-33246漏洞实现RocketMQ宿主机远程代码执行的兴奋

我依然记得自己第一次发现xss漏洞时候的兴奋: 我也记得自己第一次发现sql输入时候的快乐: 直到最近我终于收获了人生的第一个远程代码执行漏洞的利用&#xff08;RCE:remote code execute&#xff09;&#xff0c;虽然这个漏洞的危害远超过了前两个&#xff0c;但是快乐不如前…

RocketMQ(二):基础API

Spring源码系列文章 RocketMQ(一)&#xff1a;基本概念和环境搭建 RocketMQ(二)&#xff1a;基础API 目录 一、RocketMQ快速入门1、生产者发送消息2、消费者接受消息3、代理者位点和消费者位点 二、消费模型特点1、同一个消费组的不同消费者&#xff0c;订阅主题必须相同2、不…

伊朗黑客对以色列科技行业发起恶意软件攻击

最近&#xff0c;安全研究人员发现了一场由“Imperial Kitten”发起的新攻击活动&#xff0c;目标是运输、物流和科技公司。 “Imperial Kitten”又被称为“Tortoiseshell”、“TA456”、“Crimson Sandstorm”和“Yellow Liderc”&#xff0c;多年来一直使用“Marcella Flore…

加密磁盘密钥设置方案浅析 — LUKS1

虚拟化加密磁盘密钥设置方案浅析 前言元数据分析元数据格式整体格式头部格式加密算法密码校验key slot格式其它字段 流程验证 前言 我们在虚拟化加密磁盘密钥设置方案浅析 — TKS1中介绍了加密磁盘密钥设置方案&#xff0c;TKS1对密钥设置(Linux Unified Key Setup)的流程和方…

模拟散列表(哈希表拉链法)

维护一个集合&#xff0c;支持如下几种操作&#xff1a; I x&#xff0c;插入一个整数 x&#xff1b;Q x&#xff0c;询问整数 x 是否在集合中出现过&#xff1b; 现在要进行 N 次操作&#xff0c;对于每个询问操作输出对应的结果。 输入格式 第一行包含整数 N&#xff0c;…

举报“将我的电脑控作己用者”!

既然“麻辣800727”都说是“街子电信”干的&#xff0c;那么&#xff0c;我现在就正式举报&#xff1a;请依法管理宽带网&#xff0c;你国营的也不可以随意侵犯用户的人权&#xff0c;更不可以将自己变成法外之地&#xff01; 请公开答复&#xff0c;并改正&#xff0c;否则把…

机器学习线性代数知识补充

线性代数知识补充 正交矩阵与正交变换方阵特征值与特征向量相似矩阵对角化二次型正定二次型 正交矩阵与正交变换 方阵特征值与特征向量 相似矩阵 对角化 二次型 正定二次型

H5游戏源码分享-超级染色体小游戏

H5游戏源码分享-超级染色体小游戏 游戏玩法 不断地扩大发展同颜色的色块 用最少的步数完成游戏 <!DOCTYPE html> <html><head><meta charset"UTF-8"><meta name"viewport"content"widthdevice-width,user-scalableno,init…

应届裁员,天胡开局——谈谈我的前端一年经历

应届裁员&#xff0c;天胡开局——谈谈我的前端一年经历 许久没有更新了&#xff0c;最近一个月都在忙&#xff0c;没错&#xff0c;正如题目所说&#xff0c;裁员然后找工作… 这周刚重新上班&#xff0c;工作第二天&#xff0c;感慨良多&#xff0c;记录些什么吧。 去年十…

学习samba

文章目录 一、samba介绍二、samba的主要进程三、配置文件四、例子 一、samba介绍 1、SMB&#xff08;Server Message Block&#xff09;协议实现文件共享&#xff0c;也称为CIFS&#xff08;Common Internet File System&#xff09;。 2、是Windows和类Unix系统之间共享文件的…

【Linux】gitee仓库的注册使用以及在Linux上远程把代码上传到gitee上的方法

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天为大家介绍一个在实际工作以及项目开发过程中非常实用的网站gitee&#xff0c;并教如何正确的使用这个网站以及常见问题的解决方案&#xf…

java基础-数据类型

1、变量 变量就是申请内存来存储值。也就是说&#xff0c;当创建变量的时候&#xff0c;需要在内存中申请空间。 内存管理系统根据变量的类型为变量分配存储空间&#xff0c;分配的空间只能用来储存该类型数据。 因此&#xff0c;通过定义不同类型的变量&#xff0c;可以在内…

MySQL主主复制

主1 192.168.66.15 主2 192.168.66.16 主1&#xff1a; roottest2 ~]# hostname master1 [roottest2 ~]# bash [rootmaster1 ~]# vim /etc/my.cnf server-id11 log-binmysql-bin auto_increment_increment2 auto_increment_offset1 replicate-do-dbdemo_db …

appium+python自动化测试

获取APP的包名 1、aapt即Android Asset Packaging Tool&#xff0c;在SDK的build-tools目录下。该工具可以查看apk包名和launcherActivity 2、在android-sdk里面双击SDK-manager,下载buidl-tools 3、勾选build-tools&#xff0c;随便选一个版本&#xff0c;我这里选的是24的版…

ESP32/ESP8266基于Arduino框架下驱动1.8“tft_oled屏幕仿数码管时钟

ESP32/ESP8266基于Arduino框架下驱动1.8"tft_oled屏幕仿数码管时钟 &#x1f4cd;相关篇《ESP32基于Arduino框架下U8g2驱动I2C OLED 时间显示》&#x1f4fa;效果演示&#xff1a; &#x1f33f;屏幕显示部分&#xff0c;采用使用TFT_eSPI库驱动&#xff0c;利用该库自带的…

【SQLite】的使用及指令| 编程操作(增删改查)

一、SQLite 使用和指令集 SQLite 的基本使用SQL 命令 二、常见的 SQL 数据类型 三、SQLite的命令用法 四、SQLite的编程操作 五、sqlite3_open函数 六、sqlite3_close函数 七、sqlite3_errcode函数 八、SQLite C Interface 九、sqlite3_exec函数 十、callback回调函数 十一、…

vue:如何把后端传过来的数组的其中一个对象加入新的属性

加入我们是更改数组中的第一个对象&#xff0c;在vue中可以使用$set方法将属性插入到第一个对象中作为属性。 Script部分&#xff1a; <script>export default {data() {return {boxes: [//模拟后端传过来的数组{id:1,name:张三},{id:2,name:李四},{id:3,name:王五},{i…

香港科技大学广州|智能制造学域机器人与自主系统学域博士招生宣讲会—中国科学技术大学专场

&#x1f3e0;地点&#xff1a;中国科学技术大学西区学生活动中心&#xff08;一楼&#xff09;报告厅 【宣讲会专场1】让制造更高效、更智能、更可持续—智能制造学域 &#x1f559;时间&#xff1a;2023年11月16日&#xff08;星期四&#xff09;18:00 报名链接&#xff1a…

【SpringBoot篇】使用Spring Cache高效处理缓存数据

文章目录 &#x1f339;简述Spring Cache&#x1f3f3;️‍&#x1f308;常用注解&#x1f33a;使用SpringCache&#x1f6f8;Cacheable注解⭐测试 &#x1f6f8;CacheEvict&#x1f38d;一次清理一条数据&#x1f38d;一次删除多条数据 Spring Cache是一个框架,只要简单加一个…