基础算法(5):滑动窗口

1.何为滑动窗口?

     滑动窗口其实也是一种算法,主要有两类:一类是固定窗口,一类是可变窗口。固定的窗口只需要一个变量记录,而可变窗口需要两个变量。

2.固定窗口

     就像上面这个图一样。两个相邻的长度为4的红色窗口,下一个窗口一定比前一个窗口少一个数据,以及多一个数据。

      橙色为切换窗口时少的那个数据,黄色为多出来的那个数据,所以可以直接沿用之前数据,并且减去橙色数据,加上黄色数据,就是下一个窗口的值了。这就是滑动窗口的一个经典思路。

2.1 例题解析

      首先题是这样的

给你一个整数数组arr和两个整数k和target。请你返回长度为k且平均值大于等于target的子数组数目。

       我们可以看到他已经确定了窗口的长度,像这种滑动窗口的问题,一般都是连续字串和连续子数组的问题,在我做过的题中还没有例外,这也是滑动窗口的应用限制,必须连续。下面让我们看看怎么写:

       (1)首先,统计前k个数的和sum,作为第一个窗口的值,并且判断是否满足sum>=target,如果满足,则计数器加一;

       (2)然后,窗口开始右移,以后每次通过前一个相邻窗口,计算得到下一个窗口的值,并且判断条件是否满足满足则计数器加一;

       (3)返回计数器的值;

nclude<iostream>
int numOfSubarrays(int* arr, int arrSize, int k, int target)
{int r;int sum = 0;int cnt = 0;for (r = 0; r < k; r++){sum += arr[r];}if (sum >= target)cnt++;for (r = k; r < arrSize; r++){sum -= arr[r - k];sum += arr[r];if (sum >= target)cnt++;}return cnt;
}

2.2 leetcode固定窗口题目及模板总结

2.2.1 定长字串中元音的最大数目  
class Solution {
public:int check(char c)//每次遇到一个字符都需要进行判断,所以我们自己实现一个函数,避免重复代码{if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'){return 1;}return 0;}int maxVowels(string s, int k) {int n=s.size();int r=0;//窗口边界int cnt=0;//计数器int sum=0;//比较迭代的变量for(;r<n;r++)//开始遍历{cnt+=check(s[r]);//向窗口内添加元素if(r>=k)//窗口长度大于给定值{cnt-=check(s[r-k]);滑动直到长度等于k,减去左边元素,向右不断滑动}sum=max(sum,cnt);//将sum和cnt的值进行比较,这里sum其实起到了比较作用,将cnt的值存储到sum中}return sum;}
};
2.2.2 长度最小的子数组

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int r;int result=INT32_MAX;int sum=0;int i=0;for(r=0;r<nums.size();r++){sum+=nums[r];while(sum>=target){result=min(result,r-i+1);sum-=nums[i++];}}return result==INT32_MAX?0:result;}
};

       从这两道题中我们看到了一些相似的代码,这就是

2.2.3 固定窗口长度模板
int subarrays(int* arr, int k, int target)
{ int n=arr.size();//数组长度int r;//窗口边界int cnt = 0;//一般用来求和或者计数,视题目而定int sum = 0;//比较迭代的变量for (; r < n; r++)//开始遍历{cnt += arr[r];//向窗口内添加元素if (r >= k)//窗口长度大于给定值{cnt -= arr[r - k]; //减去左边元素,向右不断滑动,直到长度等于k}sum = max(sum, cnt);//更新sum的值,将sum和cnt的值进行比较,这里sum其实起到了比较作用,将cnt的值存储到sum中}return sum;
}

3.非固定窗口

3.1 例题解析

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。

     这个题怎么写呢?这个可没有说求固定长度,你翻转最多k个0之后连续1的长度最大,这个长度就是数组中连续1的最大个数,那我们就把固定长度不固定就ok了啊,下面看代码解析:

int longestOnes(vector<int>& nums, int k) {int n=nums.size();//数组/字符串长度int sum=0;//用于统计子数组/子区间是否有效,看题目要求,可能是求和/计数int l=0;//双指针,代表遍历的区间int zerocnt=0;//统计0的个数for(int r=0;r<n;r++){if(nums[r]==0)zerocnt++;//满足题目要求,计数器+1while(zerocnt>k)//翻转0的个数大于k{if(nums[l++]==0)zerocnt--;//那就开始滑动窗口了,左边界开始滑动,这时候需要判断左边界的数是不是0,是0则计数器-1,滑动到计数器的值等于k}sum=max(sum,r-l+1);//更新sum的值}return sum;}
};

     相信看完代码之后大家会发现,固定长度的滑动窗口,while循环的条件都是比较长度,而非固定长度的滑动窗口,虽然不是比较长度,但也有其他的条件进行限制,具体什么条件就需要看具体的题目了。

3.2 leetcode非固定窗口题目及模板总结

3.2.1 字符串的排列

class Solution {
public:bool checkInclusion(string s1, string s2) {//滑动窗口unordered_map<char, int> win, need;//将子串的元素压入哈希表for (auto &i : s1){++need[i];}//定义边界int right = 0, left = 0, n = s1.size(), num = s2.size(), count = 0;//进行滑动窗口for(;right < num;right++){//如果可以在哈希表中找到元素就压入到窗口中if (need.find(s2[right]) != need.end()){++win[s2[right]];if (need[s2[right]] == win[s2[right]]){++count;}}while(right - left + 1 >= n){if (count == need.size()){return true;}//缩小窗口if (need.find(s2[left]) != need.end()){//缩小窗口的步骤其实跟扩大窗口的步骤是相反的if (need[s2[left]] == win[s2[left]]){--count;}--win[s2[left]];}left++;}}return false;}
};
3.2.2 最短超串

class Solution {
public:vector<int> shortestSeq(vector<int>& big, vector<int>& small) {int n=big.size();//数组长度unordered_map<int,int>win,need;//定义两个哈希表,一个存储子数组,一个存储窗口for(auto a:small)//将子数组压入哈希表中便于查找和比较{need[a]++;}int l=0,r=0;//定义双指针(变量)作边界vector<int>ans;//定义一个数组用来存储最短子数组的左端点和右端点int count=0;//计数器,用来计算长数组出现子数组元素的次数,便于条件处理int len=INT_MAX;//可以不断更新的长度len//开始滑动窗口for(;r<n;r++){//扩大窗口if(need.find(big[r])!=need.end()){win[big[r]]++;if(need[big[r]]==win[big[r]])//防止重复{count++;  }}//开始缩小窗口while(count==need.size()){//进行获取最短超串if(len>r-l+1)//判断下一个窗口是否比上一个窗口长度小,如果小则更新len和ans数组的值{ans={l,r};len=r-l+1;}如果此时窗口左端的值在子数组的哈希表中耀进行特殊处理if(need.find(big[l])!=need.end()){if(need[big[l]]==win[big[l]]){count--;}win[big[l]]--;}l++;}}return ans;}
};
3.3.3 非固定窗口模板
int slidingWindow(vector<int> nums) {int n = nums.size();int ans = 0;// 记录窗口内的元素及其个数,非必要map<int, int> um;// l:窗口左边界; r:窗口右边界int l = 0, r = 0;// r 指针负责探索新的区间,直到搜索到nums的某末尾for(;r < n;r++) {um[r]++;// 如果区间不满足条件,l指针右移,窗口收缩while (区间[l, r] is Invalid) {um[l]--;l++;}// 此处处理结果, deal with(ans, 区间[l, r])res = max(ans, r - l + 1); // 或者res = min(ans, r - l + 1);}return ans;
}

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

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

相关文章

Axure中动态面板使用及轮播图多种登录方式左侧导航栏之案列

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《产品经理如何画泳道图&流程图》 ⛺️ 越努力 &#xff0c;越幸运 目录 一、轮播图简介 1、什么是轮播图 2、轮播图有什么作用 3、轮播图有什么特点 4、轮播图适应范围 5、…

智能 GPT 图书馆又重生了

智能 GPT 图书馆又重生了 作者&#xff1a;程序员小白条 1&#xff09;概述 自从大二寒假准备开始筹备这个项目&#xff0c;到现在已经一年了&#xff0c;这个项目能维护一年&#xff0c;不愧是我.jpg。本来这个项目只是想练练手&#xff0c;因为那时候刚学完 Spring Boot2 V…

Elasticsearch安装部署

Elasticsearch安装部署 1.下载elasticsearch安装包&#xff1a;Elasticsearch 2.4.6 | Elastic 下载中文分词器&#xff1a;Release v1.10.6 medcl/elasticsearch-analysis-ik GitHub 2.安装elasticsearch rpm -ivh elasticsearch-2.4.6.rpm 3.安装中文分词器插件 首先在…

20.链路聚合二层

链路聚合二层 大意&#xff1a;拉多根线&#xff0c;捆绑到一块&#xff0c;让交换机认为是一个逻辑的接口 增加带宽的同时&#xff0c;还能起到链路冗余的作用 链路聚合分为二层链路聚合与三层链路聚合 二层链路聚合 不需要配置IP地址 两台PC配置好IP后默认情况下是可以相互…

sqlserver dba日常操作

文章目录 查询慢sql的方法sqlserver备份全备差异备日志备ldf备份事务备份 注意事项SQL Server 还原全备还原差异备份还原日志备/尾日志还原事务日志还原备份还原中的问题还原失败&#xff0c;需要某些权限重命名sql Server数据库名称失败 作业迁移单个迁移批量迁移 登陆账号迁移…

软件开发模型(架构师复习资料)

在计算机刚刚诞生的年代&#xff0c;计算机是一种只有天才才能掌握的工具。人们对软件的认知仅仅停留在程序的层面上&#xff0c;所谓的软件开发就是那些能够掌握计算机的天才们写的一些只有计算机才能理解的二进制序列。但随着技术的发展&#xff0c;软件的复杂度不断提高&…

安装android studio

记录一下安装android studio的过程&#xff1a; 1.首先安装android studio到某一文件夹后&#xff0c;在C盘用户目录下可以看到.android文件夹。C:\Users\22515\AppData\Local\Google目录下也会出现AndroidStudio2022.2文件夹。&#xff08;注意&#xff1a;用户名&#xff0c…

算法通关第十九关-青铜挑战理解动态规划

大家好我是苏麟 , 今天聊聊动态规划 . 动态规划是最热门、最重要的算法思想之一&#xff0c;在面试中大量出现&#xff0c;而且题目整体都偏难一些对于大部人来说&#xff0c;最大的问题是不知道动态规划到底是怎么回事。很多人看教程等&#xff0c;都被里面的状态子问题、状态…

maui中实现加载更多 RefreshView跟ListView(2)

一个类似商品例表的下拉效果&#xff1a; 代码 新增个类为商品商体类 public class ProductItem{public string ImageSource { get; set; }public string ProductName { get; set; }public string Price { get; set; }}界面代码&#xff1a; <?xml version"1.0&quo…

Missing artifact org.wltea.analyzer:ik-analyzer:jar:5.0

没有找到【org.wltea.analyzer】 找到了【org.wltea.ik-analyzer】 https://github.com/wks/ik-analyzer https://github.com/wks/ik-analyzer.git https://code.google.com/archive/p/ik-analyzer/downloads?page2 C:\Users\Administrator\Desktop\ik-analyzer-master>m…

用bash写脚本

本章主要介绍如何使用bash写脚本。 了解通配符 了解变量 了解返回值和数值运算 数值的对比 判断语句 循环语句 grep的用法是“grep 关键字 file”&#xff0c;意思是从file中过滤出含有关键字的行。 例如&#xff0c;grep root /var/log/messages&#xff0c;意思是从/var/log/…

IDEA添加Apifox插件后,返回参数不详细解决办法

Apifox官方文档地址(文档中返回的是特殊情况&#xff0c;跟我现在项目的返回不一样&#xff0c;因此需要更改配置) 点击跳转到官方API地址 实现步骤分为两步&#xff1a;第一步&#xff1a;添加配置&#xff0c;第二步使用注解。 1.添加配置 打开Idea设置&#xff0c;添加配置…

带你学C语言~指针(2)

目录 &#x1f3c9;前言 &#x1f680; 数组名的理解 &#x1f680;使用指针访问数组 ✈一维数组传参的本质 ✈冒泡排序 &#x1f3c6;二级指针 &#x1f3c6;指针数组 &#x1f3c6;指针数组模拟二维数组 &#x1f389;结束语 &#x1f3c9;前言 上一章&#xff0c;小…

element组件库的日期选择器如何限制?

本次项目中涉及到根据日期查找出来的数据进行调整,所以修改的数据必须是查找范围内的数据.需要对调整数据的日期进行限制,效果如下: 首先我们使用了element 组件库的日期选择器,其中灌完介绍, picker-options中函数disabledDate可以设置禁用状态,代码如下: <el-date-pickerv…

【SpringBoot】参数校验及异常处理

实现注册功能时经常遇到参数校验的问题。 参数校验 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency>参数前添加注解&#xff0c;并指定校验规…

【数据分析之Numpy】Numpy中复制函数numpy.repeat()与numpy.tile()的使用方法及区别

一、简介 numpy.repeat()与numpy.tile()都是Numpy库中的复制函数&#xff0c;用于将数组中的元素重复指定的次数。 numpy.repeat()函数接受三个参数&#xff1a;要重复的数组、重复的次数和重复的轴。 numpy.tile()函数接受两个参数&#xff1a;要重复的数组和重复的次数。 二…

Github 2023-12-18 开源项目周报 Top14

根据Github Trendings的统计&#xff0c;本周(2023-12-18统计)共有14个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量TypeScript项目4Python项目4Jupyter Notebook项目3非开发语言项目1JavaScript项目1Rust项目1Go项目1 基于项目…

自然语言处理阅读第二弹

HuggingFace 镜像网站模型库 NLP中的自回归模型和自编码模型 自回归&#xff1a;根据上文内容预测下一个可能的单词&#xff0c;或者根据下文预测上一个可能的单词。只能利用上文或者下文的信息&#xff0c;不能同时利用上文和下文的信息。自编码&#xff1a;对输入的句子随…

MyBatis的查询方法!!!

准备工作&#xff1a;1.创建一个maven工程&#xff0c;然后将pojo类导入到项目中去。 2.导入依赖到pom.xml文件中 3.在resources中创建log4j.properites和mybatis-config.xml 4.创建UserMapper接口和UserMapper.xml文件 5.创建测试类MyBatisTest 1.创建Maven工程&#xff0c;还…

Windows 安装RocketMQ

1.rocketmq下载 https://archive.apache.org/dist/rocketmq/5.1.4/ 2.环境准备 64位JDK 1.8; Maven 3.2.x; 64位操作系统系统&#xff0c;本文档在Windows上安装 3.解压到一个无中文无空格的目录下&#xff0c;解压后目录如下&#xff1a; 配置环境变量 4.更改配置 java的…