算法学习笔记:双指针_滑动窗口专题

目录

1.长度最小的子数组

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

3.将x减少到0的最小操作数

4.最大连续1的个数Ⅲ

5.找到字符串中所有字母异位词

6.水果成篮

7.串联所有单词的子串

8.最小覆盖子串

1.长度最小的子数组:209. 长度最小的子数组 - 力扣(LeetCode)中等

2.无重复字符的最长子串:3. 无重复字符的最长子串 - 力扣(LeetCode)中等

3.将x减少到0的最小操作数:1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)中等

4.最大连续1的个数Ⅲ:1004. 最大连续1的个数 III - 力扣(LeetCode)中等

5.找到字符串中所有字母异位词:438. 找到字符串中所有字母异位词 - 力扣(LeetCode)中等

6.水果成篮:904. 水果成篮 - 力扣(LeetCode)中等

7.串联所有单词的子串:30. 串联所有单词的子串 - 力扣(LeetCode)困难

8.最小覆盖子串:76. 最小覆盖子串 - 力扣(LeetCode)困难

滑动窗口。1.特点:具有单调性。2.步骤:进窗口、判断窗口、出窗口。然后记录结果在三个步骤其一

1.长度最小的子数组

(1)链接:209. 长度最小的子数组 - 力扣(LeetCode)中等

题意:找到一个最短的子数组(连续),要求子数组的和>=目标值。

(2)思路:滑动窗口不断求和,当和>=目标值时,则判断结果并出窗口

可以使用滑动窗口的原因是:数组元素都是正整数,不断向右递增时数组和是递增的

(3)代码

class Solution {public int minSubArrayLen(int target, int[] nums) {int ret = Integer.MAX_VALUE, sum = 0;for(int left=0,right=0;right<nums.length;right++) {sum += nums[right]; //1.进窗口while(sum >= target) { //2.判断ret = Math.min(right-left+1,ret); //3.记录结果sum -= nums[left++]; //4.出窗口}}return ret==Integer.MAX_VALUE?0:ret;}
}
2.无重复字符的最长子串

(1)链接:3. 无重复字符的最长子串 - 力扣(LeetCode)中等

题意:找出没有重复字符的最长子数组,也就是求最长子数组的长度

(2)思路:也是找子数组,所以可以使用滑动窗口。

如何判断是否有重复元素,则可以遍历窗口内元素即可

(3)代码

class Solution {public int lengthOfLongestSubstring(String s) {//如何判断窗口内是否有重复元素??从窗口左边开始遍历,是否和新进入的窗口值相同//做法:始终保持窗口内的元素是不重复的int ret = 0;int n = s.length();for(int left=0,right=0;right<n;right++) {//1.入窗口--这里默认窗口为[left,right]的元素int cur = left;while(cur < right) { //2.判断-窗口内是否有重复元素if(s.charAt(cur) == s.charAt(right)) {left = cur+1; //3.出窗口}cur++;}ret = Math.max(ret,right-left+1); //4.记录结果-此时的窗口内保证无重复元素}return ret;}
}
3.将x减少到0的最小操作数

(1)链接:1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)中等

题意:每次从最左或者最右选取一个数(选取完默认从数组中删除),要求和为x且长度最小的。这是正向的意思,我们反过来理解:在中间选取一段连续区间和为sum-x,要求长度最长

(2)思路:连续数组且都是正整数,且和为sum-x

(3)代码

class Solution {public int minOperations(int[] nums, int x) {//题意:每次选择最左边或者最右边的数,是否可以组合成x。//题意转换:数组和为sum,是否存在这样一个区间,使得和为sum-x的,要长度最大int sum = 0, n = nums.length;for(int i=0;i<n;i++) {sum += nums[i];}int target = sum - x, len = -1, path = 0;for(int left=0,right=0;right<n;right++) {path += nums[right]; //1.入窗口while(left < n && path > target) { //2. 判断//3.出窗口path -= nums[left];left++;}//4.记录结果if(path == target) len = Math.max(len,right-left+1);}return len==-1?-1:n-len;}
}
4.最大连续1的个数Ⅲ

(1)链接:1004. 最大连续1的个数 III - 力扣(LeetCode)中等

题意:找出含有最多1的子数组,有k次机会可以将0变成1

(2)思路:连续子数组,可以使用滑动窗口。窗口内维护1的个数和将0变成1的次数

出窗口的条件:当0的个数大于K次时出窗口

(3)代码

class Solution {public int longestOnes(int[] nums, int k) {//窗口内维护1,和可将0变成1的个数int n = nums.length;int ret = 0, count=0;for(int left=0,right=0;right<n;right++) {if(nums[right] == 0) count++; //1.入窗口while(count > k) { //2.判断//3.出窗口if(nums[left] == 0) count--;left++;}//4.记录结果ret = Math.max(ret,right-left+1);}return ret;}
}
5.找到字符串中所有字母异位词

(1)链接:438. 找到字符串中所有字母异位词 - 力扣(LeetCode)中等

题意:给两个字符串,要求在s字符串中找出所有和p字符串互为异位词的字符串

(2)思路:(窗口不断向右移动,字母的数量是不断增加的)窗口只需要维护p长度的大小即可,每次到达该长度,就判断一下是否互为异位词,判断完记录结果并出窗口。

用两个计数数组判断是否互为异位词

(3)代码

class Solution {public List<Integer> findAnagrams(String s, String p) {//如何判断异位词??int[] pMap = new int[26];for(int i=0;i<p.length();i++) {pMap[p.charAt(i)-97]++;}int[] sMap = new int[26];List<Integer> ret = new ArrayList<>();for(int left=0,right=0;right<s.length();right++) {//1.入窗口sMap[s.charAt(right)-97]++;//2.判断if(right-left+1 == p.length()) {//3.判断是否为异位词boolean update = true;for(int i=0;i<26;i++) {if(sMap[i] != pMap[i]) {update = false;break;}}//4.记录结果if(update) ret.add(left);//5.出窗口sMap[s.charAt(left++)-97]--;}}return ret;}
}
6.水果成篮

(1)链接:904. 水果成篮 - 力扣(LeetCode)中等

题意:给一个数组,不同的值代表不同的水果。最多只能采摘两种水果,求可以采摘的最多数量是多少?

(2)思路:不断向右移动,数量增加,且是连续子数组。

每次入窗口判断对应的map是否为空,为空则为不同的种类。当种类数大于2说明超出需要出窗口;最后记录结果即可。

(3)代码

class Solution {public int totalFruit(int[] fruits) {//如何判断水果的种类和之前的相同或者不同??可以用map记录,如果=0则不同int[] map = new int[fruits.length];int ret = 0, kind = 0;for(int left = 0,right = 0; right < fruits.length; right++) {//1.入窗口并判断水果种类是否增加if(map[fruits[right]] == 0) {kind++;}map[fruits[right]]++;//2.判断-种类是否超出2种while(kind > 2) {//3.出窗口map[fruits[left++]]--;if(map[fruits[left-1]] == 0) kind--;}//4.记录结果ret = Math.max(ret,right-left+1);}return ret;}
}
7.串联所有单词的子串

(1)链接:30. 串联所有单词的子串 - 力扣(LeetCode)困难

题意:有一个字符串数组words,里面的字符串长度都相同,把它们以任何的顺序组成一个字符串(单个单词内部顺序不变)。然后求该字符串在字符串s中出现的起始位置

(2)思路:把整个单词看成一个字母,也就是找这些字母的异位词出现的起始位置

1)先用Map存储words中字符串出现的频率

2)滑动窗口每次移动len步,每次进入窗口的单词为right+len

3)进入窗口后,同时记录map中,并判断该单词是否为有效单词,如果有效则记录count

4)如果count达到有效次数,则记录结果

5)滑动窗口需要执行len次

(3)代码:

class Solution {public List<Integer> findSubstring(String s, String[] words) {int n = words.length, len = words[0].length();Map<String,Integer> mapW = new HashMap<>(); //记录words里面单词出现的频率for(String x : words) {mapW.put(x,mapW.getOrDefault(x,0)+1);}List<Integer> ret = new ArrayList<>();for(int k=0;k<len;k++) { //控制滑动窗口执行的次数Map<String,Integer> mapS = new HashMap<>(); //记录窗口内里面单词出现的频率for(int left=k,right=k,count=0;right+len <= s.length();right+=len) {//每次进窗口为right+len, 用count记录窗口内有效字符串的个数//1.进窗口String in = s.substring(right,right+len); //[right,right+len-1]mapS.put(in,mapS.getOrDefault(in,0)+1);//2.维护窗口内有效字符串个数if(mapS.get(in) <= mapW.getOrDefault(in,0)) count++; //如果in字符串在mapW也存在,且个数<=,说明是有效字符串//3.判断if(right-left+1 > len * n) {String out = s.substring(left,left+len);if(mapS.get(out) <= mapW.getOrDefault(out,0)) count--; //如果out字符串在mapW也存在,且个数<=,说明是有效字符串//4.出窗口mapS.put(out,mapS.get(out)-1);left += len;}//5.记录结果if(count == n) ret.add(left);}}return ret;}
}

(*)不使用该计数数组,使用map如果做?

1)借助一个变量count统一窗口中有效“字符”的个数。这里的字符可能是单个字母,也可能是一个字符串。

2)进窗口时,判断两个hash中的字符个数,如果进窗口的hash个数小于原hash个数

8.最小覆盖子串

(1)链接:76. 最小覆盖子串 - 力扣(LeetCode)困难

题意:在字符串s中找出一个连续的子串,要求这个子串包含字符串t。并且要返回这个最短的子串

(2)思路:使用两个哈希表或者计数数组,维护有效数字的窗口即可。

只需要记录最短的长度和起始位置。

(3)代码

使用Map接口:

class Solution {public String minWindow(String s, String t) {Map<Character,Integer> mapT = new HashMap<>();for(int i=0;i<t.length();i++) {char ch = t.charAt(i);mapT.put(ch,mapT.getOrDefault(ch,0)+1);}int minLen = Integer.MAX_VALUE, begin = -1;Map<Character,Integer> mapS = new HashMap<>();for(int left = 0,right = 0,count = 0;right < s.length();right++) {//1.入窗口char ch = s.charAt(right);mapS.put(ch,mapS.getOrDefault(ch,0)+1);//2.判断是否有效if(mapS.get(ch) <= mapT.getOrDefault(ch,0)) count++;//3.维护窗口while(left <= right && count >= t.length()) {//4.记录结果if(count == t.length() && minLen > right - left + 1) {begin = left;minLen = right - left + 1;}//5.出窗口char out = s.charAt(left);if(mapS.get(out) <= mapT.getOrDefault(out,0)) count--;mapS.put(out,mapS.get(out)-1);left++;}           }if(begin == -1) return new String();else return s.substring(begin,begin+minLen);}
}

使用数组模拟:

class Solution {public String minWindow(String ss, String tt) {char[] s = ss.toCharArray();char[] t = tt.toCharArray();int[] mapT = new int[128];//记录第一轮mapint kinds = 0;for(int i = 0;i < t.length;i++) {if(mapT[t[i]] == 0) kinds++;mapT[t[i]]++;}int[] mapS = new int[128];int minlen = Integer.MAX_VALUE, begin = -1;for(int left=0,right=0,count=0;right<s.length;right++) {//1.入窗口char in = s[right];mapS[in]++;//2.判断是否为有效种类if(mapS[in] == mapT[in]) count++;//3.循环while(count == kinds) {//4.记录窗口if(right-left+1 < minlen) {begin = left;minlen = right-left+1;}//5.出窗口char out = s[left++];if(mapS[out] == mapT[out]) count--;mapS[out]--;}}if(begin == -1) return new String();else return ss.substring(begin,begin+minlen);}   
}

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

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

相关文章

Witsbb健敏思是哪个国家的品牌?澳洲纯净溯源,100+过敏原排除的敏宝专研品牌

在为敏感体质宝宝挑选营养补充品时&#xff0c;“品牌来源是否可靠”“品控标准是否严格”往往是宝爸宝妈的首要考量。源自澳大利亚的Witsbb健敏思&#xff0c;作为澳企Forestpark旗下的综合膳食营养补充品牌&#xff0c;从诞生起便根植于澳洲严苛的保健品监管体系&#xff0c;…

gdbserver远程调试和交叉编译gdb

1、交叉编译gdb 1.1下载源码 Gdb源码&#xff1a;wget https://ftp.gnu.org/gnu/gdb/gdb-15.2.tar.xz Gdb依赖的源码&#xff1a;GMP、MPFR、ncurses&#xff08;图形库&#xff09; GMP源码&#xff1a;wget https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz MPFR源码&#xff1…

UE5.5模型导入FBX强制x轴向前Force Front XAxis

很多软件轴向都是不同的 , 所以模型导入虚幻的时候 可以勾选Force Front XAxisUE5.5 在右上角设置 点击右上角三个点就可以看到强制前X轴

Docker中如何记录非交互式连接ssh用户操作的所有命令记录?

网罗开发&#xff08;小红书、快手、视频号同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

涡旋场和挠场的对偶性方程组

要将涡旋场与挠场的动态对偶性以麦克斯韦方程组的形式嵌入爱因斯坦-嘉当理论的弯曲时空框架中。一、符号与几何基础1. 基本张量定义 度规张量&#xff1a; g_{\mu\nu} &#xff08;描述时空弯曲&#xff0c; \mu,\nu 0,1,2,3 &#xff09;。仿射联络&#xff1a; \Gamma^\la…

8.28日QT

思维导图#include <iostream>using namespace std;int main() {int a0,b0,c0,d0;string i;cout << "请输入一个字符串" << endl;getline(cin,i);int yi.size()-1;while(1){if(a<i[y]&&i[y]<z){aa1;}else if(A<i[y]&&i[y]…

跨网络通信:路由器如何实现全球互联

目录 一、跨网络的两台主机通信 二、采用不同通信标准的两个局域网内的主机通信 三、路由器实现的“认路”功能、数据传输&#xff1a;封装与解封装 四、认识IP地址 五、为什么访问目标主机需要经过路由器&#xff1f; 1、网络划分 2、寻址与转发 六、目的IP地址的核心意…

HTTP 头

HTTP 头&#xff08;HTTP Header&#xff09;是 HTTP 请求/响应中用于传递元数据的关键部分&#xff0c;分为 请求头&#xff08;Request Header&#xff09;、响应头&#xff08;Response Header&#xff09;、通用头&#xff08;General Header&#xff09; 和 实体头&#x…

vue 海康视频插件

背景&#xff1a; 在vue项目中&#xff0c;需要在pc端播放视频&#xff0c;播放的视频包括视频实时、视频回放等。 写文思路&#xff1a; 海康视频对接流程&#xff0c;了解海康视频插件&#xff0c;前端开发项目并引入依赖&#xff0c;前端开发封装的组件&#xff0c;组件的调…

【URP】Unity 插入自定义RenderPass

【从UnityURP开始探索游戏渲染】专栏-直达 自定义渲染通道是一种改变通用渲染管道&#xff08;URP&#xff09;如何渲染场景或场景中的对象的方法。自定义呈现通道(RenderPass)包含自己的Render代码&#xff0c;可以在注入点将其添加到RenderPass中。 添加自定义呈现通道(Rend…

DevSecOps 集成 CI/CD Pipeline:实用指南

就在你以为软件开发已无简化的余地时&#xff0c;新的解决方案应运而生 随着软件开发几乎每天都在攀升&#xff0c;组织不断尝试以前所未有的速度交付新功能和应用程序。虽然持续集成和持续交付 &#xff08;CI/CD&#xff09; Pipeline 彻底改变了软件部署&#xff0c;但它们…

vue2+elementui 表格单元格增加背景色,根据每列数据的大小 颜色依次变浅显示

注释&#xff1a; vue2elementui 表格列实现一个功能&#xff0c;给定两个颜色&#xff1a;红色 #f96d6f 和 绿色 #63be7b&#xff0c;列数据正数时表格单元格背景色为红色&#xff0c;列数据负数时表格单元格背景色为绿色&#xff0c;根据数据的大小颜色依次越来越淡&#xff…

【JavaEE】(19) MyBatis-plus

一、MyBatis Generator 为 MyBastis 框架设计的代码生成工具&#xff0c;简化持久层编码工作。根据数据库表自动生成 Java 实体类、Mapper 接口、SQL 的 xml 文件。让开发者专注于业务逻辑。 1、引入插件 MyBatis 官网搜索 MyBatis Generator 插件&#xff1a;Running MyBatis…

Android之腾讯TBS文件预览

文章目录前言一、效果图二、实现步骤1.去官网注册并创建应用[腾讯官网](https://console.cloud.tencent.com/tbs/client)2.下载arr文件并引入[腾讯TBS](https://download.csdn.net/download/Android_Cll/91764395)3.application实例化4.activity实例化5.下载网络文件6.PreviewA…

基于微信小程序的化妆品成分查询系统源码

源码题目&#xff1a;基于微信小程序的化妆品成分查询系统源码☑️ 文末联系获取&#xff08;含源码、技术文档&#xff09;博主简介&#xff1a;10年高级软件工程师、JAVA技术指导员、Python讲师、文章撰写修改专家、Springboot高级&#xff0c;欢迎高校老师、同行交流合作。毕…

STM32 启动执行逻辑与代码烧入方法详解:从底层原理到实操落地

STM32 启动执行逻辑与代码烧入方法详解&#xff1a;从底层原理到实操落地背景概要STM32启动和执行的核心逻辑链条代码烧入到STM32的途径方法结束语背景概要 在学习STM32时候我们知道代码需要通过一些下载器&#xff08;如ST-Link、J-Link&#xff09;或者串口下载烧入到STM32芯…

Go对接印度股票数据源指南:使用StockTV API

一、StockTV API简介 StockTV提供全球200国家的实时金融数据&#xff0c;覆盖股票、外汇、期货和加密货币市场。针对印度市场&#xff08;国家ID14&#xff09;&#xff0c;其主要优势包括&#xff1a; 毫秒级低延迟响应7x24小时稳定服务日均处理亿级数据免费技术支持 官方资源…

ESP8266:Arduino学习

ESP8266一&#xff1a;环境搭建使用Ardino框架&#xff0c;在官网下载&#xff0c;下载离线的支持包二&#xff1a;实现简单的项目1. 点灯{pinMode(LED_PIN, OUTPUT); // 设置引脚为输出模式digitalWrite(LED_PIN, HIGH); // 点亮 LED}I/O引脚的三种模式分别为&#xff1a;INPU…

青少年软件编程(python六级)等级考试试卷-客观题(2023年3月)

更多内容和历年真题请查看网站&#xff1a;【试卷中心 -----> 电子学会 ----> 机器人技术 ----> 六级】 网站链接 青少年软件编程历年真题模拟题实时更新 青少年软件编程&#xff08;python六级&#xff09;等级考试试卷-客观题&#xff08;2023年3月&#xff09…

mongodb influxdb

、您需要提前配置 MongoDB 和 InfluxDB。让我帮您说明配置步骤&#xff1a; MongoDB 配置 启动 MongoDB 容器后&#xff0c;进入容器创建数据库&#xff1a; # 进入 MongoDB 容器 docker exec -it mongo mongosh -u root -p 123456# 创建 product 数据库 use product# 创建集合…