滑动窗口系列(不定长滑动窗口长度)9/4

2024-09-04 13:44

本文主要是介绍滑动窗口系列(不定长滑动窗口长度)9/4,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

求子数组个数

一、乘积小于k的子数组

给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。

输入:nums = [10,5,2,6], k = 100
输出:8
解释:8 个乘积小于 100 的子数组分别为:[10]、[5]、[2]、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。
思路:

使用滑动窗口的思路,当右边界增大后,仍然满足条件的时候,此时增加的有效答案有:right-left+1.为什么呢?新增一个元素后,该元素和之前其他元素可以组成新的子数组,自己也可以作为子数组,所以有(right-left+1)个。

什么时候更新答案呢?当找到合适的left之后。

因为当更新右边界后,可能该滑动窗口不是满足条件的,所以在更新左边界之后,再计算有效的子数组。

代码:
class Solution {public int numSubarrayProductLessThanK(int[] nums, int k) {if(k<=1)return 0;int left=0;int right=0;int count=0;int multi=1;while(right<nums.length){multi*=nums[right];while(multi>=k){multi=multi/nums[left];left++;}if(multi<k)count+=right-left+1;right++;}return count;}
}

二、包含所有三种字符的子字符串数目

给你一个字符串 s ,它只包含三种字符 a, b 和 c 。

请你返回 a,b 和 c 都 至少 出现过一次的子字符串数目。

输入:s = "abcabc"
输出:10
解释:包含 a,b 和 c 各至少一次的子字符串为 "abc", "abca", "abcab", "abcabc", "bca", "bcab", "bcabc", "cab", "cabc"  "abc" (相同字符串算多次)
思路:

滑动窗口,只要找到第一个满足要求的子字符串,那么后面无论再加上什么,都是符合要求的。所以符合条件的字符串有s.length()-right;

那我们只需要找到满足要求的字符串,然后res+=s.length()-right;

            while(count[0]>=1&&count[1]>=1&&count[2]>=1){res+=s.length()-right;count[s.charAt(left)-'a']--;left++;}
代码:
class Solution {public int numberOfSubstrings(String s) {int[] count=new int[3];int left=0;int right=0;int res=0;while(right<s.length()){count[s.charAt(right)-'a']++;while(count[0]>=1&&count[1]>=1&&count[2]>=1){res+=s.length()-right;count[s.charAt(left)-'a']--;left++;}right++;}return res;}
}

三、模型(当题目中要求 出现xxx 至少xx次)

思路:

这种题我们首先要找到符合条件的滑动窗口,然后所有符合条件的结果就是 总长度-right 

 在寻找符合条件的滑动窗口的时候,用while。

class Solution {public int countKConstraintSubstrings(String s, int k) {int[] arr=new int[2];int left=0;int right=0;int count=0;while(right<s.length()){//积累条件xxx//只要满足题目中的条件 就可以加了while(题目中给定的条件){count+=s.length()-right;arr[s.charAt(left)-'0']--;left++;}right++;}return xxx}
}

四、统计完全子数组的数目
 

给你一个由  整数组成的数组 nums 。如果数组中的某个子数组满足下述条件,则称之为 完全子数组 :

  • 子数组中 不同 元素的数目等于整个数组不同元素的数目。

返回数组中 完全子数组 的数目。子数组 是数组中的一个连续非空序列。

输入:nums = [1,3,1,2,2]
输出:4
解释:完全子数组有:[1,3,1,2]、[1,3,1,2,2]、[3,1,2] 和 [3,1,2,2] 。
思路:

1.首先统计一下数组中数字的种类distinctCount以及数量。使用数组统计(因为题目中数字的大小是1-2000)

2.定义一个变量completeCount记录滑动窗口中数字的种类;定义一个数组统计滑动窗口中数字的数量

3.滑动窗口右边界停止扩大,开始收割结果的条件:completeCount==distinctCount (子数组中 不同 元素的数目等于整个数组不同元素的数目。)

然后开始收割:res+=nums.length-right; 然后左边界移动,移动的时候数量要改变,如果数量==0,种类也要改变。

代码:
class Solution {public int countCompleteSubarrays(int[] nums) {//1.统计字符的数量 以及 字符的种类int distinctCount =0;int[] count=new int[2001];for(int num:nums){count[num]++;if(count[num]==1)distinctCount++;}//2.int left=0;int right=0;int res=0;int completeCount=0;int[] window=new int[2001];while(right<nums.length){window[nums[right]]++;if(window[nums[right]]==1)completeCount++;//如果滑动窗口中的种类==总的种类while(completeCount==distinctCount){res+=nums.length-right;window[nums[left]]--;if(window[nums[left]]==0){completeCount--;}left++;}right++;}return res;}
}

五、统计好子数组的数目

给你一个整数数组 nums 和一个整数 k ,请你返回 nums 中  子数组的数目。

一个子数组 arr 如果有 至少 k 对下标 (i, j) 满足 i < j 且 arr[i] == arr[j] ,那么称它是一个  子数组。子数组 是原数组中一段连续 非空 的元素序列。

思路:

子数组中至少有k对满足条件,那么他就是一个好子数组。

1.首先我们要统计滑动窗口中有多少对满足条件的(i,j);记为 typeCount;

if(map.get(nums[right])>=2)typeCount+=map.get(nums[right])-1;

新加一个相同的数字,它就可以和前面所有的组成一个符合条件的数对。

2.如果typeCount>=k,滑动窗口的右边界就固定住。res+=nums.length-right;(因为右边界如果满足,那么以后的也一定满足)。

3.然后改变左边界,首先改变在map哈希表中的数量,然后改变typeCount;

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

 

这篇关于滑动窗口系列(不定长滑动窗口长度)9/4的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136177

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(

Java基础回顾系列-第五天-高级编程之API类库

Java基础回顾系列-第五天-高级编程之API类库 Java基础类库StringBufferStringBuilderStringCharSequence接口AutoCloseable接口RuntimeSystemCleaner对象克隆 数字操作类Math数学计算类Random随机数生成类BigInteger/BigDecimal大数字操作类 日期操作类DateSimpleDateForma

Java基础回顾系列-第三天-Lambda表达式

Java基础回顾系列-第三天-Lambda表达式 Lambda表达式方法引用引用静态方法引用实例化对象的方法引用特定类型的方法引用构造方法 内建函数式接口Function基础接口DoubleToIntFunction 类型转换接口Consumer消费型函数式接口Supplier供给型函数式接口Predicate断言型函数式接口 Stream API 该篇博文需重点了解:内建函数式

Java基础回顾系列-第二天-面向对象编程

面向对象编程 Java类核心开发结构面向对象封装继承多态 抽象类abstract接口interface抽象类与接口的区别深入分析类与对象内存分析 继承extends重写(Override)与重载(Overload)重写(Override)重载(Overload)重写与重载之间的区别总结 this关键字static关键字static变量static方法static代码块 代码块String类特