算法通过村第十六关-滑动窗口|青铜笔记|滑动很简单

文章目录

  • 前言
  • 滑动窗口的基本思想
  • 入门题目练习
    • 子数组最大平均数
    • 最长连续递增序列
  • 总结


前言


提示:我宁愿做自己,做卑微的自己,也不愿做别人,无论那会多么快乐。 --《美丽新世界》

我们在数组和链表的部分就已经接触到了双指针的思想,这里我们继续扩展了解滑动窗口的思想。滑动窗口其实也是双指针的一种特殊场景,这种方式可以很好的解决一些特定场景的问题,就有了”滑动窗口思想“

滑动窗口的基本思想

在数组和链表的章节,都强调过移动元素的方法。有一些经典的例子,推荐回顾再看一下⭐⭐⭐:

算法通过村第三关-数组白银笔记|数组双指针_师晓峰的博客-CSDN博客

算法通关村第一关-链表白银挑战笔记|公共子节点_师晓峰的博客-CSDN博客

于是慢慢的方式更加完善,这就有了”双指针的思想“

在数组双指针里,我们介绍过”对撞型”、“快慢型“两种方式,而滑动窗口思想其实也就是快慢型的特例。我们在学习计算机网络的同学都直到欢动窗口协议(Sliding Window Protocol),该协议是TCP实现流量控制等核心策略之一。事实上与流量控制,熔断、限流、超时等场景下都会首先从滑动窗口的角度来思考问题,比如Hystrix,sentinel等框架都使用了这种思想。

滑动窗口的思想非常简单,如下图,假如窗口的大小是3,当不断有新数据来的时候,我们便维护一个大小为3的一个区间,超过3的就将新的加入,老的移走。

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

有了区间,造其题目来就很容易了,例如让你找序列上连续数字的最大和最小,或者平均数,等等问题把

在这里插入图片描述
从上面看,刚才的形容是不是非常形象,所谓的窗口就是建立两个索引,left和right,并保持{left,right}之间的长度不变,然后一遍遍历,一遍寻找目标,每次更改目标要求就可以。

当然上面的例子已经告诉我们什么是窗口,什么是滑动的窗口:

  • 窗口:窗口其实就是两个变量left和right之间的元素,也可以理解为一个区间。窗口的大小可能是固定的,也可能是变换的,如果是固定大小的,那么自然要考虑是否越界,在执行处理逻辑。如果不是固定的,就要优先判断是否满足要求,再执行逻辑处理。
  • 滑动:说明这个窗口是移动的,事实上移动的仍然是left和right两个变量,而不是序列中的元素。当变量移动的时候,其中间的元素必然也会发生变化,因此就有了不断滑动的效果。

在实际问题中,窗口大小不一定是固定的,我们可以思考以下两种场景:

  1. 固定窗口的滑动就是火车行驶这种大小不变的移动
  2. 可变的窗口就是两个老师带着一队学生外出,一个负责开路,一个负责断后,中间则是小朋友。两个老师直接的距离有可能大有可能小,但是整体窗口是不断滑动向前的

所以根据窗口大小是否固定,就衍生出两种类型的题目:

  1. 固定窗口:一般让你求那个窗口的元素最大,最小、平均值、和最大、和最小等等类型的问题。
  2. 窗口变化:则一般是让你求序列最大、最小窗口是什么等等。

滑动窗口题目本身没有很大难度,但是在实际的解答中还是比较难搞的,主要是以下原因:

  1. 容器:数组,让人头疼的边界问题,稍不注意,就全盘皆输。
  2. 元素处理:比较、判断等处理方式上不仅需要借助集合等工具,还要处理技巧,不熟悉的话拿不下来。
  3. 堆:堆的接口很适合做数据处理。在固定的区间找最大、最小等问题上有很大优势。一次常常滑动窗口会和堆一起使用完美的解决很多复杂问题。

最后的疑惑:双指针和滑动窗口有什么区别?

根据性质可以看出,滑动窗口就是双指针应用的特例,主要是关注两个指针间的元素情况,因此范围更小,双指针的应用范围更广,花样更多。

入门题目练习

滑动窗口的题目在于窗口的大小变或者不变,根据这两种类型,我们就先来练练手吧.

子数组最大平均数

参考题目介绍:643. 子数组最大平均数 I - 力扣(LeetCode)

在这里插入图片描述
在这里插入图片描述
这是经典的滑动窗口的例子,况且大小都规定了,我们只要先读取k个,然后让窗口向前移动就可以了,思路和上图一模一样.

直接展示代码:

    /*** 子数组最大平均数 I* @param nums* @param k* @return*/public static double findMaxAverage(int[] nums, int k) {int len = nums.length;if ((k > len) || (len < 1) || (k < 1)) {return 0;}// 第一步确定窗口大小int windowSum = 0;for (int left = 0; left < k; left++) {windowSum += nums[left];}// 第二步 遍历维护窗口  保留窗口,处理元素int res = windowSum;for(int right = k; right < len; right++){windowSum += (nums[right] - nums[right - k]);res = Math.max(res,windowSum);}return (double) res / k;}

最长连续递增序列

参考题目介绍:674. 最长连续递增序列 - 力扣(LeetCode)

在这里插入图片描述
在这里插入图片描述
根据实例我们看图:

在这里插入图片描述
可以看到,最长的递增子序列为{1,3,5},所以返回3.在遍历的时候从第第一个元素开,先定义窗口区间[left,right),

表示递增序列,具体操作如下:

  1. 如果当前遍历到的元素比左边的那个元素要严格大,right就增加;
  2. 相反,left就跳到right的其实位置,重新计算.

这里看下代码怎么写:

/*** 674. 最长连续递增序列* @param nums* @return*/
public static int findLengthOfLCIS_1(int[] nums) {int len = nums.length;;int left = 0,right = 0;int res = 0;while(right < len){// 严格递增 right++// 相反 right 赋值给left (本质也是快慢指针问题if (right >0 && nums[right - 1] >= nums[right]){left = right;}right++;res = Math.max(res,right - left);}return res;
}

上面的代码中,序列在[left,right)下严格递增,区间的长度是right-left.

这里还有很多解法,另外一种简单的思路是一遍遍历,一边统计每个递增区间的长度.如果长度超过之前所有的区间,就保留,代码写起来也很容易:

    /*** 674. 最长连续递增序列** @param nums* @return*/public static int findLengthOfLCIS_2(int[] nums) {int currentSum = 1;int res = 1;for (int i = 1; i < nums.length; i++) {if (nums[i - 1] >= nums[i]) {// 说明不满足条件,重新计数currentSum = 1;}else{currentSum++;}res = Math.max(res, currentSum);}return res;}

当然本题目你如果不知道滑动窗口,也可以做的,不要觉得它过于神秘,只是个名字而已,掌握方法,看透本质才是主要的.


总结

提示:滑动窗口;双指针;快慢指针变体;滑动窗库概念;滑动窗口核心理解


如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ ("▔□▔)/

如有不理解的地方,欢迎你在评论区给我留言,我都会逐一回复 ~

也欢迎你 关注我 ,喜欢交朋友,喜欢一起探讨问题。
在这里插入图片描述

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

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

相关文章

实现vue项目和springboot项目前后端数据交互

1、安装node.js 太高版本的win7不支持 这里安装node-v12.16.2-x64.msi&#xff0c;指定安装位置后直接按下一步就可以。npm是node内置的工具 这里配置npm的镜像cnpm&#xff08;提高下载速度&#xff0c;以后用到npm的命令都可以用cnpm命令替换&#xff09;不指定cnpm版本使用…

【USMA】N1CTF2022-praymoon

前言 本题主要利用 USMA 解题&#xff0c;当然还有其他做法&#xff0c;暂时不表 程序分析 启动脚本就不看了&#xff0c;该开的保护都开了。看下文件系统初始化脚本&#xff1a; #!/bin/shmkdir /tmp mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpf…

JS加密/解密之闭包的运用

深入探讨JavaScript闭包的演变与应用 摘要&#xff1a; 本文将深入探讨JavaScript闭包的概念、特性以及其在实际开发中的应用。我们将从闭包的起源开始&#xff0c;探讨它在JavaScript编程中的重要性&#xff0c;并通过实例展示闭包在不同场景下的灵活应用。 引言 JavaScrip…

CSS3 渐变

CSS3 渐变可以让你在两个或多个指定的颜色之间显示平稳的过渡。 CSS3渐变有两种类型&#xff1a;线性渐变&#xff08;Linear Gradients&#xff09;和径向渐变&#xff08;Radial Gradients&#xff09;。 线性渐变&#xff08;Linear Gradients&#xff09;&#xff1a; 线性…

点击查看详情 | 网页版微信客户管理系统如何操作试用?

微信作为我们日常生活中最常用的社交应用之一&#xff0c;早已成为我们与朋友、家人和同事保持联系的重要工具&#xff0c;也是营销引流的重要平台。 通过微信营销&#xff0c;可以比较精准定向亲近用户。而微信的功能并没有很能满足做微信营销的人群&#xff0c;所以我们需要借…

linux复习笔记02(小滴课堂)

linux下输入输出错误重定向&#xff1a; 输入重定向&#xff1a;< 一个大于号是进行了覆盖。 两个大于号是追加。 输出重定向可以用于以后日志打印。 错误重定向&#xff1a; 错误重定向是不把信息打印到屏幕上而是打印到指定文件中去&#xff1a; 输出重定向其实是用的1…

基于TCP的RPC服务

TCP服务器上的RPC&#xff0c;通过创建一个服务器进程监听传入的tcp连接&#xff0c;并允许用户 通过此TCP流执行RPC命令 -module(tr_server). -author("chen"). -behaviour(gen_server).%% API -export([start_link/1,start_link/0,get_count/0,stop/0 ]).-export(…

Android问题笔记 - 关于SuperNotCalledException报错异常信息的解决方案

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…

屏幕录像推荐:Apeaksoft Screen Recorder 中文 for mac

Apeaksoft Screen Recorder 是一款功能强大的屏幕录制软件&#xff0c;它允许用户在 Windows 和 Mac 系统上捕捉和录制屏幕活动。无论是记录游戏过程、创建教学视频、制作演示文稿还是捕捉在线流媒体内容&#xff0c;该软件都提供了丰富的功能和工具。 以下是 Apeaksoft Scree…

【c++Leetcode】141. Linked List Cycle

问题入口 思想&#xff1a;Floyds Tortoise and Hare 这个算法简单来说就是设置一个慢指针&#xff08;一次移动一个位置&#xff09;和一个快指针&#xff08;一次移动两个位置&#xff09;。在遍历过程中&#xff0c;如果慢指针和快指针都指向同一个元素&#xff0c;证明环…

JAVA基础-String StringBuffer 和 StringBuilder 类(9)

目录 String创建字符串字符串长度连接字符串创建格式化字符串String 方法 **StringBuilder**StringBuffer String 创建字符串 String s1 "Runoob"; // String 直接创建 String s2 "Runoob"; // String 直接创建 String s3 s…

C语言实现模拟 strcmp 字符串比较函数,实现字符串大小的比较

完整代码&#xff1a; // 模拟 strcmp 字符串比较函数&#xff0c;实现字符串大小的比较 #include<stdio.h> //strcmp函数是两个字符串自左向右逐个字符相比&#xff08;按 ASCII 值大小相比较&#xff09;&#xff0c;直到出现不同的字符或遇 \0 为止&#xff0c;如果字…

【RNA folding】RNA折叠算法与生物物理约束

文章目录 RNA折叠RNA folding representation1 DP for simple folds1.1 Nussinov Algorithm objective1.2 energy constraints1.3 The key idea of the algorithm 2 DP for stacking and complex foldsStochastic context free grammars 来自Manolis Kellis教授&#xff08;MIT…

进制转换(二进制、八进制、十进制、十六进制)

目录 一&#xff1a;十进制转换为二进制、八进制、十六进制 &#xff08;1&#xff09;整数转换 &#xff08;2&#xff09;小数转换 1&#xff09;十进制转二进制 2&#xff09;十进制转八进制 3&#xff09;十进制转十六进制 二&#xff1a;二进制、八进制、十六进制转…

安装Sentinel

大家好今天来安装Sentinel . 安装Sentinel 下载 : 大家可以选择相应版本(最新版本1.8.6) 官网下载地址 : Release v1.8.6 alibaba/Sentinel GitHub 链接&#xff1a;Sentinel_免费高速下载|百度网盘-分享无限制 (baidu.com) 提取码&#xff1a;8eh9 运行 : 将jar包放到任…

redis怎么设计一个高性能hash表

问题 redis 怎么解决的hash冲突问题 &#xff1f;redis 对于扩容rehash有什么优秀的设计&#xff1f; hash 目标是解决hash冲突&#xff0c;那什么是hash冲突呢&#xff1f; 实际上&#xff0c;一个最简单的 Hash 表就是一个数组&#xff0c;数组里的每个元素是一个哈希桶&…

EasyCVR视频汇聚平台显示有视频流但无法播放是什么原因?该如何解决?

视频汇聚/视频云存储/集中存储/视频监控管理平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、云存储、智能分析等&#xff0c;视频智能分析平台EasyCVR融合性强、开放度…

【LeetCode 算法专题突破】滑动窗口(⭐)

文章目录 前言1. 长度最小的子数组题目描述代码 2. 无重复字符的最长子串题目描述代码 3. 最大连续1的个数 III题目描述代码 4. 将 x 减到 0 的最小操作数题目描述代码 5. 水果成篮题目描述代码 6. 找到字符串中所有字母异位词题目描述代码 7. 串联所有单词的子串题目描述代码 …

asp.net特色商品购物网站系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net特色商品购物网站系统 是一套完善的web设计管理系统&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 vs2010&#xff0c;数据库为sqlserver2008&a…

动手实现H5仿原生app前进后退切换效果

动手实现H5仿原生app前进后退切换效果 前言 最近在优化H5页面&#xff0c;我注意到当开发完成的移动端H5页面嵌入到微信小程序或者原生app中时&#xff0c;当触发页面路由切换会与原生app看上去有点格格不入&#xff0c;因为H5页面<router-view>切换路由时是直接替换了…