滑动窗口用法

文章目录

  • 1. 长度最小的子数组(模板)
  • 2. 无重复字符的最长字串
  • 3. 最小覆盖字串
  • 4. 加油站
  • 5. 替换字串得到平衡字符串

1. 长度最小的子数组(模板)

image-20240310211503255

  1. 题目分析
直接用步骤分析示例1,[]表示窗口,min_length表示满足条件的最短子数组,sum表示窗口内元素的总值:- [2],3,1,2,4,3		min_length=100001,sum=2 < target=7- [2,3],1,2,4,3		min_length=100001,sum=5 < target=7- [2,3,1],2,4,3		min_length=100001,sum=6 < target=7- [2,3,1,2],4,3		min_length=4,     sum=8 >= target=7- PS:只要sum>=target,就尝试将左窗口向右移动,若仍满足条件,就更新min_length,不行就继续- [2,3,1,2,4],3		min_length=5,	  sum=12 >= target=7- 2,[3,1,2,4],3		min_length=4,	  sum=10 >= target=7- 2,3,[1,2,4],3		min_length=3,	  sum=7 >= target=7- 2,3,[1,2,4,3]		min_length=4,	  sum=10 >= target=7- 2,3,1,[2,4,3]		min_length=3,	  sum=9 >= target=7- 2,3,1,2,[4,3]		min_length=2,	  sum=7 >= target=7- 最后返回min_length=2
  1. 代码实现
def minSubArrayLen(target, nums):""":type target: int:type nums: List[int]:rtype: int"""n = len(nums)# l表示左窗口的位置,r表示右窗口的位置l = r = 0# sum表示窗口内的元素总值sum = nums[0]# 如果第一个元素的值就大于等于target,直接返回if sum >= target:   return 1# 设置成100001是因为测试用例的数组长度最长为100000min_length = 100001# 循环n - 1次for i in range(1, n):# 右窗口肯定是要一直移动的,不存在每次循环不移动的情况r += 1sum += nums[r]# 如果sum去掉靠近左窗口的那个元素后仍然大于sum,就该减小窗口的长度了while sum - nums[l] >= target:sum -= nums[l]l += 1# 经过上述步骤后,当来到右窗口此时的位置时,满足条件的窗口长度就得到了if sum >= target:min_length = min(min_length, r - l + 1)# 数组所有元素的总和加起来都小于target,min_length就返回0return 0 if min_length == 100001 else min_length

image-20240310215745912

  1. 精简版
def minSubArrayLen(target, nums):""":type target: int:type nums: List[int]:rtype: int"""n = len(nums)l = r = 0min_length = 100001sum = 0while r < n:sum += nums[r]while sum - nums[l] >= target:sum -= nums[l]l += 1if sum >= target:min_length = min(min_length, r - l + 1)r += 1return 0 if min_length == 100001 else min_length

image-20240310221133426

2. 无重复字符的最长字串

image-20240310222352348

注意s字符串包含:字母、数字、符号和空格

  1. 题目分析:
以abcabcbb为例,max_length表示最长无重复字串字串,l表示左窗口,r表示右窗口:- [a]bcabcbb		max_length=1- [ab]cabcbb		max_length=2- [abc]abcbb		max_length=3- [abca]bcbb- 下面这一步就很重要了,l=max(l,a上一次出现位置+1)- a[bca]bcbb		max_length=3- a[bcab]cbb		l=max(l,b上一次出现位置+1)- ab[cab]cbb		max_length=3- ab[cabc]bb		l=max(l,c上一次出现位置+1)- abc[abc]bb		max_length=3- abc[abcb]b		l=max(l,b上一次出现位置+1)- abcab[cb]b		max_length=3- abcab[cbb]		l=max(l,b上一次出现位置+1)- abcabcb[b]		max_length=3
  1. 代码实现
def lengthOfLongestSubstring(s):""":type s: str:rtype: int"""n = len(s)# 字母、数字、空格和一些符号的ascii码都在0~255之间pos = [-1] * 255l = 0max_length = 0for r in range(n):# 在r移动到下一个字符位置时,一定要先让l获取上次这个字符出现的位置并且加1l = max(l, pos[ord(s[r])] + 1)# 然后再更新这个字符出现的位置pos[ord(s[r])] = r# 最后通过比较获得wu'cmax_length = max(max_length, r - l + 1)return max_length

image-20240310230922966

3. 最小覆盖字串

image-20240311171925285

  1. 题目分析
1. 拿一个cnts数组统计t串中字符的出现次数,total记录t中每个字符出现次数的总和
2. 首先,t中字符每出现一次,cnts[ord(t[i])] -= 1
3. 然后开始循环s字符串
4. 如果遇到出现次数小于0的,total就减-1
5. 每循环一次,该字符的出现次数就加1(我们只关注t中的字符,s中其它字符正常加就行了,后面不会涉及到它们)
6. 当total == 0时,也就是说当前窗口中已经包含了t中所有字符
7. 开始判断,左窗口所指向的字符出现次数是否大于0,大于0左窗口就可以向右移动了
8. PS:当total第一次等于0时,表示窗口中恰好有t中每个字符,且它们的出现次数都为0,后续可能会有多余的,它们的出现次数就会大于0,s中其它字符最开始都是0,只要在窗口中,它们的出现次数就会大于0
9. 然后判断当前窗口的长度跟最小覆盖字串的长度比较,取较小的那个cnts是统计所有字符的出现次数,初始化为0- 首先是将t串中每个字符的出现次数减1,也就是说,除了t串中的字符出现次数是负数,其它字符的出现次数都是0- 然后就是只要有一个字符进窗口,出现次数加1- 当左窗口字符出现次数大于0时,就可以考虑将其删除了
  1. 代码实现
def minWindow(s, t):""":type s: str:type t: str:rtype: str"""n = len(s)m = len(t)# 如果s串长度小于m长度,s就不可能有长度大于等于m的字串if n < m:return ""total = m# 计数数组cnts = [0] * 255# 给t串中每种字符出现次数为负数for i in range(m):cnts[ord(t[i])] -= 1l = 0target = ''min_length = 100001# 开始遍历s串for r in range(n):# 能满足下面if语句条件的一定是t串中的字符if cnts[ord(s[r])] < 0:total -= 1# 不管是哪个串中的字符,次数都要加1cnts[ord(s[r])] += 1# total==0表示窗口中已经包含了t串所有字符if total == 0:# 开始判断左窗口可不可以移动while cnts[ord(s[l])] > 0:cnts[ord(s[l])] -= 1l += 1# 取最小覆盖字串的长度if r - l + 1 < min_length:min_length = r - l + 1target = s[l : r + 1]return target

image-20240311201530260

4. 加油站

image-20240311210500668

  1. 题目分析
用左窗口遍历一遍加油站即可,此时左窗口就相当于起点,右窗口就从左窗口开始向后遍历,只要出现油不够的情况,左窗口就向右移动。可以将gas和cost数组合并来看,例如:
gas 	= [1,2,3,4,5]
cost	= [3,4,5,1,2]
combine = [-2,-2,-2,3,3]
combine[0]表示从第0个加油站开到第1个加油站倒欠2升油,所以无法以第0个加油站为起点,开到第一个加油站
combine[3]表示从第4个加油站开到第5个加油站多出了3升油,所以能以第4个加油站为起点,开到第五个加油站
  1. 代码
def canCompleteCircuit(gas, cost):""":type gas: List[int]:type cost: List[int]:rtype: int"""n = len(gas)# sum表示路上的总油量,只要油量小于0了,就不能走sum = 0# len表示一共走了几个加油站length = 0for l in range(n):while sum >= 0:# 如果从某个加油站出发,能走完一圈,就返回那个加油站的位置if length == n:return lr = (l + length) % nlength += 1sum += gas[r] - cost[r]# 走到这说明sum<0了,那么左窗口就该移动了,且sum要减去左窗口移动之前所在位置的那个值,len也要减1sum -= gas[l] - cost[l]length -= 1# 如果以每个加油站为起点出发,sum最后都会小于0,就返回-1return -1

image-20240311212755937

5. 替换字串得到平衡字符串

image-20240311221316817

  1. 题目分析
思路:
1. 先统计每种字符的出现次数
2. 然后用窗口框柱一段字符,假设窗口外的每种字符出现次数不等于 n/4,判断只替换窗口内的字符能否使窗口外的每种字符字符出现次数都变成n/4
3. 如果该窗口不行,那么它的子窗口一定不行(这里没想出为什么)如果[l,r-1]不行,[l,r]行,那么[l+1,r]也有可能行,[l+1,r-1]就一定不行4. 那么怎么实现第二步?假如窗口长度为8,窗口外面字符出现次数为Q->18,W->19,E->16,R->19,要求是每种字符出现20次8-(20-18) = 66-(20-19) = 55-(20-16) = 11-(20-19) = 0最后剩余0,表示能行如果外面某种字符超过了平均出现次数,那么这个窗口一定不行
  1. 代码实现
def balancedString(s):""":type s: str:rtype: int"""# 这个函数就是实现上面分析的第四步# len表示窗口的大小,也就是有len个元素可以替换,看能不能使窗口外面的每种字符出现次数达到averdef ok(cnts, len, aver):for i in range(4):if cnts[i] > aver:return Falselen -= aver - cnts[i]return True if len == 0 else Falsen = len(s)aver = n // 4# 将Q映射成0,W映射成1,E映射成2,R映射成3data = ['Q', 'W', 'E', 'R']cnts = [0] * 4for i in range(n):cnts[data.index(s[i])] += 1# 作为替换字串的最小长度返回ans = nr = 0# 左窗口开始遍历sfor l in range(n):# l-r表示[l,r)范围# 如果当前窗口不行,右窗口jiwhile ok(cnts, r - l, aver) == False and r < n:# 右窗口每次向右移动都会在窗口内新加入一个字符,它在窗口外的出现次数要减1cnts[data.index(s[r])] -= 1r += 1# 这里是为了判断上面循环是因为第一个条件结束还是因为第二个条件结束的# 若是因为第二个条件结束的,就说明这个窗口是合法的,当然这里只能判断第一个条件# 因为第一个条件也有可能不符合if r != n:ans = min(ans, r - l)# 最后一次循环结束后,左窗口会向右移动,相当于会将它原来所在位置的字符排除到窗口外,所以在窗口外这个字符的出现次数要加1cnts[data.index(s[l])] += 1return ans

image-20240311230406213

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

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

相关文章

软件测试级别和对应要求

软件测试级别指的是将软件测试活动按照不同的开发阶段和测试目的进行分类&#xff0c;形成不同层次的测试过程。 分级依据&#xff0c;根据V模型 单元测试&#xff1a;这是软件生命周期中的第一个测试级别&#xff0c;主要针对软件的最小单元模块进行&#xff0c;例如类、函数…

Robotstudio2024中从备份文件恢复和创建工作站的具体方法演示

Robotstudio2024中从备份文件恢复和创建工作站的具体方法演示 如下图所示,打开Robotstudio2024软件,有需要的可以从以下链接获取: ABB机器人编程仿真软件RobotStudio 2024.1-链接baiduyun 点击“新建”—工作站—创建, 如下图所示,点击“ABB模型库”,选择自己使用的机器…

Proxmox VE qm 方式一键创建Linux虚拟机

前言 实现qm 方式一键创建Linux虚拟机&#xff0c;提高效率。 qm 一键创建Linux 虚拟机 以下实现在线下载镜像&#xff0c;创建虚拟机&#xff0c;安装系统需要自己手动安装哦&#xff0c;如果想实现全自动安装系统&#xff0c;建议部署自己的内网pxe server 系统参考各参数…

EditPlus来啦(免费使用!)

hello&#xff0c;我是小索奇 今天推荐一款编辑器&#xff0c;是索奇学习JavaSE时入手滴&#xff0c;非常好用哈&#xff0c;小索奇还是通过老杜-杜老师入手滴&#xff0c;相信很多人也是通过老杜认识嘞&#xff0c;来寻找破解版或者准备入手这个间接使用的编辑器~ EditPlus是…

HarmonyOS开发实例:【菜单app】

简介 分布式菜单demo 模拟的是多人聚餐点菜的场景&#xff0c;不需要扫码关注公众号等一系列操作&#xff0c;通过分布式数据库可以方便每个人可及时查看到订单详情&#xff0c;数量&#xff0c;总额等&#xff1b;效果如下 demo效果 工程目录 完整的项目结构目录如下 ├…

如何编译OpenHarmony自带APP

作者&#xff1a;王石 概述 OpenHarmony 的主干代码是开源社区的重要学习资源&#xff0c;对于想进行应用开发和熟悉 OpenHarmony 能力的同学主干代码是非常重要的资源&#xff0c;在主干代码的 applications 目录里聚集了很多原生的应用实现&#xff0c;那么如何编译这些代码…

广州南沙番禺联想SR530服务器主板传感器故障维修

今日分享一例广州市南沙区联想ThinkSystem SR530服务器sensor sysbrd vol故障问题维修案例&#xff1b; 服务器型号是&#xff1a;Lenovo thinksystem sr530 g6服务器 服务器所在位置&#xff1a;广东省广州市南沙区 服务器故障问题&#xff1a;机房异常停电&#xff0c;来电后…

【Entity Framework】EF连接字符串和模型

【Entity Framework】EF连接字符串和模型 文章目录 【Entity Framework】EF连接字符串和模型一、概述二、使用 Code First 按约定创建连接三、使用 Code First 和指定的数据库名称按约定创建连接四、将 Code First 与 app.config/web.config 文件中的连接字符串结合使用五、将 …

请核对您的姓名、证件号码、有效期和年限是否选择正确,请勿使用挂失过的身份证

问题 请核对您的姓名、证件号码、有效期和年限是否选择正确&#xff0c;请勿使用挂失过的身份证 详细问题 笔者在专利业务办理系统进行新用户注册&#xff0c;注册时间为晚上大概22&#xff1a;00以后。注册时已核对姓名、证件号码、有效期和年限&#xff0c;已确保正确&…

LinkedHashMap部分底层源码解析

JDK版本为1.8.0_271&#xff0c;LinkedHashMap继承了HashMap&#xff0c;LinkedHashMap在HashMap的基础上维护了一个双向链表&#xff0c;实现了可以根据插入顺序/访问顺序&#xff08;accessOrderfalse/true&#xff09;访问Map集合。 关于HashMap的原理可以参考HashMap部分底…

RabbitMQ-死信队列常见用法

目录 一、什么是死信 二、什么是死信队列 ​编辑 三、第一种情景&#xff1a;消息被拒绝时 四、第二种场景&#xff1a;. 消费者发生异常&#xff0c;超过重试次数 。 其实spring框架调用的就是 basicNack 五、第三种场景&#xff1a; 消息的Expiration 过期时长或队列TTL…

基于特征的多模态生物信号信息检索与自相似矩阵:专注于自动分割

论文地址&#xff1a;Biosensors | Free Full-Text | Feature-Based Information Retrieval of Multimodal Biosignals with a Self-Similarity Matrix: Focus on Automatic Segmentation (mdpi.com) 论文源码&#xff1a;无 期刊&#xff1a;biosensors 这篇论文提出了一种基…

kafka(六)——存储策略

存储机制 kafka通过topic作为主题缓存数据&#xff0c;一个topic主题可以包括多个partition&#xff0c;每个partition是一个有序的队列&#xff0c;同一个topic的不同partiton可以分配在不同的broker&#xff08;kafka服务器&#xff09;。 关系图 partition分布图 名称为t…

利用细粒度检索增强和自我检查提升对话式问题解答能力

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 论文标题&#xff1a;Boosting Conversational Question Answering with Fine-Grained Retrieval-Augmentation and Self-Check 论文地址&#xff1a;https://arxiv.org/abs/2403.18243 检索增强生成…

程序“猿”自动化脚本(一)

1.剪贴板管理器&#x1f4cb; 您是否曾经发现自己在处理多个文本片段时忘记了复制的内容&#xff1f;有没有想过有一个工具可以跟踪您一天内复制的所有内容&#xff1f; 该自动化脚本会监视您复制的所有内容&#xff0c;将每个复制的文本无缝存储在时尚的图形界面中&#xff0c…

阿里云4核16G服务器可以用来做什么?

阿里云4核16G服务器可以用来做什么&#xff1f;可用来搭建游戏服务器&#xff0c;阿里云4核16G服务器10M带宽30元1个月、90元3个月&#xff0c;优惠活动 aliyunfuwuqi.com/go/youhui 阿里云4核16G服务器可以用来做什么&#xff1f;除了搭建游戏服务器&#xff0c;还可以用来哪…

基于 GPIO 、Pinctl子系统、设备树的LED 驱动程序

理论部分&#xff1a; 编写思路&#xff1a; GPIO 的地位跟其他模块&#xff0c;比如 I2C 、 UART 的地方是一样的&#xff0c;要使用某个引脚&#xff0c;需要先把引脚配置为 GPIO 功能&#xff0c;这要使用 Pinctrl 子系统&#xff0c;只需要在设备 树里指定就可以。在…

力扣HOT100 - 41. 缺失的第一个正数

解题思路&#xff1a; 原地哈希 就相当于&#xff0c;让每个数字n都回到下标为n-1的家里。 而那些没有回到家里的就成了孤魂野鬼流浪在外&#xff0c;他们要么是根本就没有自己的家&#xff08;数字小于等于0或者大于nums.size()&#xff09;&#xff0c;要么是自己的家被别…

springCloud项目打包 ,maven package或install打包报错

解决思路一&#xff1a; <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version></plugin><plugin>&…

【应急响应事件】记一次矿机木马事件

事情起因&#xff0c;是因为实验室有一台服务器的占用率从开机启动就是100%&#xff0c;很怀疑就是中了某种矿机木马&#xff0c;拿去挖矿了&#xff0c;然后经过师兄的不懈努力&#xff0c;终于找到了木马文件&#xff0c;给他命名为virus_sample 然后我就拿着样本去逆了 木马…