滑动窗口系列(定长滑动窗口长度)8/31

ops/2024/9/23 10:20:39/

1.长度为K子数组中的最大和

给你一个整数数组 nums 和一个整数 k 。请你从 nums 中满足下述条件的全部子数组中找出最大子数组和:

  • 子数组的长度是 k,且
  • 子数组中的所有元素 各不相同 
题意:

在之前题目的基础上添加了一个条件:子数组中的所有元素各不相同 。

因此在这里使用哈希表记录元素出现的次数

思路:

在循环中

1.首先要判断该数字之前是否出现过? 如果出现过,就要将滑动窗口的左边界移动到该数字的下一个。

            while (map.getOrDefault(nums[right], 0) != 0) {map.put(nums[left], map.get(nums[left]) - 1);sum -= nums[left];left++;}

2.然后sum累计求和(第一步中判断了没有出现过才加的),如果滑动窗口的长度==k,此时更新一下最大值,然后移动滑动窗口的左边界并且更新一下哈希表;

            sum += nums[right];map.put(nums[right], map.getOrDefault(nums[right], 0) + 1);if (right - left + 1 == k) {max = Math.max(max, sum);sum -= nums[left];map.put(nums[left], map.get(nums[left]) - 1);left++;}

3.返回最大值

代码:
 class Solution {public long maximumSubarraySum(int[] nums, int k) {long max = 0;int left = 0;int right = 0;long sum = 0;Map<Integer, Integer> map = new HashMap<>();while (right < nums.length) {while (map.getOrDefault(nums[right], 0) != 0) {map.put(nums[left], map.get(nums[left]) - 1);sum -= nums[left];left++;}sum += nums[right];map.put(nums[right], map.getOrDefault(nums[right], 0) + 1);if (right - left + 1 == k) {max = Math.max(max, sum);sum -= nums[left];map.put(nums[left], map.get(nums[left]) - 1);left++;}right++;}return max;}
}

2.爱生气的书店老板(有点绕)

题意:

有一个书店,开了n分钟,每一分钟会进x个人,用数组customers表示;这老板脾气有点大,每一分钟可能会生气,用数组grumpy表示;如果生气的话,顾客就会不满意;但是老板有一个秘诀,会抑制生气,只能抑制minutes分钟;求n分钟最多满意的顾客有多少人?

输入:customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], minutes = 3
输出:16
解释:书店老板在最后 3 分钟保持冷静。
感到满意的最大客户数量 = 1 + 1 + 1 + 1 + 7 + 5 = 16.
思路:

1.首先假设不会抑制情绪,那么顾客数为最少的,人数记为basic;

   for(int i=0;i<customers.length;i++){if(grumpy[i]==0)basic+=customers[i];}

2.选择在何时抑制情绪,这里可以使用滑动窗口的思路;

   2.1 遍历数组,如果该分钟老板是生气的,那么顾客数就要在basic的基础上增加

   2.2 然后要判断滑动窗口的长度,如果==minutes,那么就要更新最大值,并且更新滑动窗口的边           界    

        while(right<customers.length){if(grumpy[right]==1)basic+=customers[right];if(right-left+1==minutes){max=Math.max(max,basic);if(grumpy[left]==1)basic-=customers[left];left++;}right++;}
代码:
class Solution {public int maxSatisfied(int[] customers, int[] grumpy, int minutes) {int left=0;int right=0;int max=Integer.MIN_VALUE;int basic=0;for(int i=0;i<customers.length;i++){if(grumpy[i]==0)basic+=customers[i];}while(right<customers.length){if(grumpy[right]==1)basic+=customers[right];if(right-left+1==minutes){max=Math.max(max,basic);if(grumpy[left]==1)basic-=customers[left];left++;}right++;}return max;}
}

3.子串出现的最大次数()

题意:

给你一个字符串 s ,请你返回满足以下条件且出现次数最大的 任意 子串的出现次数:

  • 子串中不同字母的数目必须小于等于 maxLetters 。
  • 子串的长度必须大于等于 minSize 且小于等于 maxSize 。
输入:s = "aababcaab", maxLetters = 2, minSize = 3, maxSize = 4
输出:2
解释:子串 "aab" 在原字符串中出现了 2 次。
它满足所有的要求:2 个不同的字母,长度为 3 (在 minSize 和 maxSize 范围内)。
思路:只需要看minSize就可以,因为长度为maxSize的字符串一定是覆盖长度为minSIze的字符串的;eg:bcdabcdabcdabc minSize=3 maxSize=4 abcd会出现3次,abcd出现abc一定出现;

因此这道题就变成了,滑动窗口长度为minSize,寻找不同字母的数量要<=maxLetters的字符串。这个字符串可能有多个,返回一个数量最多的。

代码:
class Solution {public int maxFreq(String s, int maxLetters, int minSize, int maxSize) {int left=0;int right=0;int count=0;int max=0;Map<Character,Integer> map1=new HashMap<>();//记录滑动窗口中出现字母的次数Map<String,Integer> map2=new HashMap<>();//记录符合字符串出现的次数while(right<s.length()){char ch=s.charAt(right);if(map1.getOrDefault(ch,0)==0)count++;map1.put(ch,map1.getOrDefault(ch,0)+1);if(right-left+1==minSize){if(count<=maxLetters){String str=s.substring(left,right+1);map2.put(str,map2.getOrDefault(str,0)+1);max=Math.max(max,map2.get(str));}map1.put(s.charAt(left),map1.get(s.charAt(left))-1);if(map1.get(s.charAt(left))==0)count--;left++;}right++;}return max;}
}

4.最小交换次数来组合所有的1 II

题意:

交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。

环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻 。

给你一个 二进制环形 数组 nums ,返回在 任意位置 将数组中的所有 1 聚集在一起需要的最少交换次数。

思路:

要组合所有的1,我们可以将滑动窗口的长度设置为1的个数;

如果滑动窗口中0的个数为0:就不需要交换,交换次数为0;

如果滑动窗口中0的个数为1:就需要将1和这个0交换,交换次数为1;

因此,0的个数就是需要交换的个数;

因此只需要使用滑动窗口判断里面0的个数即可。并且更新最小值;

注意:是循环数组

left和right的增加都需要对size取余

代码:
class Solution {public int minSwaps(int[] nums) {//计算窗口的长度(数组中1的个数就是窗口的长度)int windowSize=0;for(int num:nums)if(num==1)windowSize++;int left=0;int right=0;int res=Integer.MAX_VALUE;int count=0;int index=0;while(index<windowSize+nums.length-1){if(nums[right]==0)count++;if(right-left+1==windowSize||right+nums.length-left+1==windowSize){res=Math.min(res,count);if(nums[left]==0)count--;left=(left+1)%nums.length;}right=(right+1)%nums.length;index++;}return res==Integer.MAX_VALUE?0:res;}
}


http://www.ppmy.cn/ops/103957.html

相关文章

【Python系列】text二进制方式写入文件

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

斑马线识别检测系统源码分享

斑马线识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Visio…

Spring MVC RESTful API - 修改状态接口示例

前言 在许多应用程序中&#xff0c;更新资源的状态是一项常见的需求。例如&#xff0c;在任务管理系统中&#xff0c;用户可能需要更新任务的状态&#xff0c;如从“待办”变为“完成”。为了实现这一功能&#xff0c;我们可以使用Spring MVC框架结合MyBatis Plus来创建一个简…

vim 简易配置

set nocompatible set backspace2 "--------------display----------------- set nu "行号 syntax on "语法高亮 set ruler "显示当前行和列 set showcmd "显示部分命令 set showmode "最后一行显示当前模式 "set match "显示括号匹配…

谈一谈JVM的GC(垃圾回收)

JVM&#xff08;Java Virtual Machine&#xff09;的GC&#xff08;Garbage Collection&#xff0c;垃圾回收&#xff09;是Java语言的一个重要特性&#xff0c;它负责自动管理内存&#xff0c;释放那些不再被使用的对象所占用的内存空间。以下是对JVM GC的详细介绍&#xff1a…

【大数据】浅谈java程序开发怎么转型为大数据开发

文章目录 一、引言二、技术能力要求1. 编程基础2. 数据结构和算法3. 数据库知识4. 分布式系统原理5. 云计算基础6. 大数据技术栈7. 数据仓库和数据湖8. 数据挖掘和机器学习9. 数据可视化 三、学习资源1. 在线课程平台2. 官方文档和教程3. 技术社区和论坛4. 书籍 四、考取证书1.…

浏览器播放RTSP流,支持H264、H265等格式,支持IE、Chrome等浏览器

目录 背景 解决方案 效果 代码 前端代码 后端代码 下载 背景 项目中需要在浏览器中播放RTSP流&#xff0c;实在是不想折腾ActiveX控件 1、麻烦&#xff08;开发麻烦、使用时设置也麻烦&#xff09; 2、非IE浏览器不兼容 解决方案 使用OpenCvSharpNancy写一个解码服…

论文笔记:GEO-BLEU: Similarity Measure for Geospatial Sequences

22 sigspatial 1 intro 提出了一种空间轨迹相似性度量的方法比较了两种传统相似度度量的不足 DTW 基本特征是它完全对齐序列以进行测量&#xff0c;而不考虑它们之间共享的局部特征这适用于完全对齐的序列&#xff0c;但不适用于逐步对齐没有太多意义的序列BLEU 适用于不完全…