四、滑动窗口-算法总结

文章目录

  • 四、滑动窗口
    • 4.1 模板
    • 4.2 示例
      • 4.2.1 最小覆盖子串
      • 4.2.2 字符串的排列
      • 4.2.3 找到字符串中所有字母异位词
      • 4.2.4 无重复字符的最长子串

四、滑动窗口

4.1 模板

/* 滑动窗口算法框架 */
void slidingWindow(string s, string t) {unordered_map<char, int> need, window;for (char c : t) need[c]++;int left = 0, right = 0;int valid = 0;while (right < s.size()) {// c 是将移入窗口的字符char c = s[right];// 右移窗口right++;// 进行窗口内数据的一系列更新...// 判断左侧窗口是否要收缩while (window needs shrink) {// d 是将移出窗口的字符char d = s[left];// 左移窗口left++;// 进行窗口内数据的一系列更新...}}
}

需要变化的地方

  • 1、右指针右移之后窗口数据更新
  • 2、判断窗口是否要收缩
  • 3、右指针右移之后窗口数据更新
  • 4、根据题意计算结果

4.2 示例

4.2.1 最小覆盖子串

76. 最小覆盖子串
在这里插入图片描述

// 使用Map的存储方式
class Solution {public String minWindow(String s, String t) {// 1、创建用于保存滑动窗口包含的字符集的mapMap<Character,Integer> winChars =  new HashMap<>();// 2、创建保存子串中的字符集的map(注意重复的字符会累计次数)Map<Character,Integer> tChars = new HashMap<>();Integer temp;for(char c:t.toCharArray()){tChars.put(c,(temp=tChars.get(c)) == null?1:(temp+1));}int tCharNum = tChars.size(); // 子串中不同字符的个数int winCharNum = 0; // 滑动窗口中已匹配子串字符的个数(相同的字符要个数上匹配)int i = 0,j = 0; // 定义滑动窗口的左右边界int start = 0,end = 0; // 定义最终的滑动窗口的左右边界(即:最小尺寸的滑动窗口)int minWinLength = Integer.MAX_VALUE; // 初始化最小的滑动窗口值// 基于滑动窗口//先右移右指针直至包含所有的子串中的字符集, 再进行滑动窗口左边界右移while(j < s.length()){char c = s.charAt(j);if(tChars.get(c) != null){ // 若是子串中的字符, 记录当前的字符winChars.put(c,(temp=winChars.get(c)) == null?1:(temp+1));if(winChars.get(c).equals(tChars.get(c))){ // 判断是否已经有字符被完全匹配完(个数)winCharNum++;}}j++; // 右移滑动窗口,注意此处操作会指向最小窗口右边界的下一个位置(由于字符子串获取是左闭右开)// 右移左边界(即:滑动窗口中已匹配完所有的子串字符)while(winCharNum == tCharNum){// 记录当前的滑动窗口长度if(j - i < minWinLength){start = i;end = j;minWinLength = j - i;}char leftChar = s.charAt(i);if(tChars.get(leftChar) != null){ // 若右移左边界排除了一个子串中的字符if(winChars.get(leftChar).equals(tChars.get(leftChar))){ // 该字符刚好个数完全匹配,则右移左边界会使总匹配个数减一// 也可能滑动窗口中匹配的字符个数大于子串中该字符的个数winCharNum--;}winChars.put(leftChar,winChars.get(leftChar)-1); // 更新滑动窗口中的字符集}i++;}}if(minWinLength == Integer.MAX_VALUE){ // 若没有更新,则返回空串return "";}return s.substring(start,end);}
}
// 使用数组的存储方式
class Solution {
public String minWindow(String s, String t) {// 技巧:用数组代替Map// 保存滑动窗口字符集int[] winMap = new int[256];// 保存需要出现的字符集int[] tMap = new int[256];for (char c : t.toCharArray()) {tMap[c]++;}// 计算共出现了多少不同的字符int charNum = 0;for (int n : tMap) {if (n > 0) {charNum++;}}// 滑动窗口左右边界int left = 0;int right = 0;// 匹配数int match = 0;// 窗口调整前暂存原窗口边界int start = 0;int end = 0;// 窗口长度的最小值int minValue = Integer.MAX_VALUE;while (right < s.length()) {char c = s.charAt(right);// 在需要的字符集里面,添加到窗口字符集里面if (tMap[c] != 0) {winMap[c]++;// 如果当前字符的数量匹配需要的字符的数量,则match值+1if (tMap[c] == winMap[c]) {match++;}}right++;// 当所有字符数量都匹配之后,开始缩紧窗口while (match == charNum) {// 获取结果if (right - left < minValue) {minValue = right - left;start = left;end = right;}char leftChar = s.charAt(left);// 左指针指向不在需要字符集则直接跳过if (tMap[leftChar] != 0) {// 左指针指向字符数量和需要的字符相等时,右移之后match值就不匹配则减一if (winMap[leftChar] == tMap[leftChar]) {match--;}winMap[leftChar]--;}left++;}}if (minValue == Integer.MAX_VALUE) {return "";}return s.substring(start, end);
}
}

4.2.2 字符串的排列

567. 字符串的排列
在这里插入图片描述

// 使用数组的存储方式
class Solution {public boolean checkInclusion(String s1, String s2) {// 创建保存滑动窗口中字符集的数组int[] wChars = new int[256];// 创建保存子串字符集的数组(累计字符个数)int[] tChars = new int[256];// 记录子串的字符for(char c:s1.toCharArray()){tChars[c]++;}int tCharNum = 0; // 子串不同字符的个数 for(int i:tChars){if(i>0){tCharNum++;}}int left = 0,right = 0; // 滑动窗口的左右边界int winCharNum = 0; // 记录滑动窗口中匹配字符的数量(具有多个相同字符需要被匹配完)// 滑动窗口算法// 先右移有边界直至窗口内匹配完所有子串字符,接着做一左边界while(right < s2.length()){char c = s2.charAt(right);if(tChars[c] != 0){wChars[c]++; // 记录当前字符if(wChars[c] == tChars[c]){ // 对某一个字符完全匹配后记录数量winCharNum++;}}right++; // 此时right指向窗口右边界的右边一个位置// 右移左边界while(winCharNum == tCharNum){c = s2.charAt(left);if(tChars[c] != 0){if(wChars[c] == tChars[c]){ // 若当前字符数刚好等于子串中该字符的数量,则再减少一个就减少匹配数winCharNum--;if(right - left == s1.length()){ // 若窗口长度等于子串长度则为排列匹配return true;}}// 更新窗口中字符的信息wChars[c]--;}left++;}}return false;}
}

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

438. 找到字符串中所有字母异位词
在这里插入图片描述

class Solution {public List<Integer> findAnagrams(String s, String p) {// 创建保存窗口中字符集的数组int[] wChars = new int[256];// 创建保存子串的字符集信息(累计字符个数)int[] tChars = new int[256];for(char c:p.toCharArray()){tChars[c]++;}// 记录子串中不同字符的数量int tCharsNum = 0;for(int i:tChars){if(i>0){tCharsNum++;}}int left = 0, right = 0; // 定义滑动窗口的左右边界int wCharsNum = 0; // 记录窗口中匹配的字符个数(相同字符需数量匹配完)// 记录结果List<Integer> result = new ArrayList<>();// 滑动窗口算法// 先右移有边界直至窗口匹配完所有子串的字符,然后右移左边界while(right < s.length()){char c = s.charAt(right);if(tChars[c] != 0){ // 当前字符为子串中出现的字符wChars[c]++; // 窗口中记录当前字符if(wChars[c] == tChars[c]){ // 字符数量匹配完则记录一个字符数量wCharsNum++;}}right++;// 右移左边界while(wCharsNum == tCharsNum){c = s.charAt(left);if(tChars[c] != 0){ // 当前字符为子串中出现的字符if(tChars[c] == wChars[c]){ // 若数量相等,则取出当前字符后则记录数少1wCharsNum--;if(right - left == p.length()){ // 当前left为满足匹配要求的临界边界;right则为右边界的后面一个位置。相等时则意味则排列匹配// 记录左边界作为结果result.add(left);}}// 更新窗口字符信息wChars[c]--;}left++;}}return result;}
}

4.2.4 无重复字符的最长子串

3. 无重复字符的最长子串
在这里插入图片描述

class Solution {public int lengthOfLongestSubstring(String s) {if(s.length() < 2){return s.length();}// 保存窗口中的字符集信息int[] wChars = new int[256];int maxSubLength = 0;int left = 0, right = 0; // 定义滑动窗口的左右边界while(right < s.length()){char c = s.charAt(right);right++;wChars[c]++; // 记录窗口中的字符信息// 右移左边界收缩窗口while(wChars[c] > 1){char leftChar = s.charAt(left);left++;wChars[leftChar]--;}maxSubLength = Math.max(maxSubLength,right - left);}return maxSubLength;}
}

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

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

相关文章

QT::QComboBox自定义左击事件信号

因为QComboBox没有自定义的clink信号&#xff0c;所以自己新建一个MyComBox类继承QComboBox&#xff0c;并且添加自定义的左击信号&#xff0c;以及使用该信号连接一个槽函数 mycombobox.h #ifndef MYCOMBOBOX_H #define MYCOMBOBOX_H#include <QComboBox> #include &l…

在 Mac 上安装虚拟机怎么样,安装虚拟机与直接安装 Windows 系统有区别吗?

随着跨系统操作的不断发展&#xff0c;虚拟机技术在生产力领域扮演着越来越重要的角色。Mac作为一款主流的操作系统&#xff0c;也有着运行虚拟机的能力。接下来给大家介绍Mac装虚拟机好不好&#xff0c;Mac装虚拟机和装Windows系统一样吗的具体内容。 Mac装虚拟机好不好 Mac…

通信工程学习:什么是FDMA频分多址

FDMA&#xff1a;频分多址 FDMA&#xff08;Frequency Division Multiple Access&#xff0c;频分多址&#xff09;是一种在无线通信领域广泛应用的多址技术。该技术通过将可用的频谱资源按频率划分&#xff0c;把传输频带划分为若干较窄且互不重叠的子频带&#xff08;或称信道…

SprinBoot+Vue爱老助老服务平台的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…

c/c++面试100道

1.一道笔试题解析_哔哩哔哩_bilibili P20&#xff1a;#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER) 1、 offsetof 宏是 C 语言中用于计算结构体成员相对于结构体起始地址的偏移量的宏定义。这个宏的定义如下&#xff1a; #define offsetof(TYPE, …

JavaScript模块化——ES6模块化规范

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境&#xff1a;vscode Chrome浏览器 1.ES6 1.1ES6介绍 ES6的全称是ECMAScript 6&#xff0c;也称为ES2015&#xff0c;是JavaScript的一个重要版本&#xff0c;它引入了许多新特性和改进&#xf…

Linux搭建邮箱服务器(简易版)

本章是上一文档的简易版本搭建方式更为快速简洁&#xff08;只需要两条命令即可搭建&#xff09;&#xff0c;如果想了解更详细一些可以看我上一文档 Linux接发邮件mailx_linux mailx o365-CSDN博客文章浏览阅读857次&#xff0c;点赞25次&#xff0c;收藏19次。本文详细描述了…

独立站内容营销SOP 1.0 丨出海笔记

提到内容营销&#xff0c;可能很多朋友都听过但没深入做&#xff0c;国内跨境独立站通过内容营销做的大流量的目前不多&#xff0c;哪怕大如 Shein, Anker&#xff0c;大部分时候还是在买量获客的阶段。 但大家只要明白一点即可&#xff1a;内容做得好不好&#xff0c;直接影响…

文档智能:OCR+Rocketqa+layoutxlm

此次先记录LayoutLMv2&#xff0c;梳理相关论文&#xff0c;记录如下&#xff1a; 首先认识一下 visually-rich document understanding tasks → \to → VrDU 其次&#xff0c;the text fields of interest&#xff0c;与图像识别的感兴趣区域 region of Interest 类似&…

【脑机接口】脑机接口性能的电压波形的尖峰分类和阈值比较

Comparison of spike sorting and thresholding of voltage waveforms for intracortical brain–machine interface performance 脑机接口性能的电压波形的尖峰分类和阈值比较论文下载&#xff1a;摘要1 介绍2 方法2.1数据获取2.2spike sorting 技术2.3神经数据分析 3结果3.1神…

社交媒体的未来:Facebook如何通过AI技术引领潮流

在数字化时代的浪潮中&#xff0c;社交媒体平台不断演变&#xff0c;以适应用户需求和技术发展的变化。作为全球领先的社交媒体平台&#xff0c;Facebook在这一进程中扮演了重要角色。尤其是人工智能&#xff08;AI&#xff09;技术的应用&#xff0c;正在深刻地改变Facebook的…

搜索树和Map

一.搜索树 1.概念 二叉搜索树又叫二叉排序树&#xff0c;它可以是一颗空树也可以是具有以下性质的二叉树 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值它的左子树也分别为二…

NR intra-freq和inter-freq测量

intra-freq 测量和inter-freq测量可以分为以下几类&#xff1a; 1 SSB based intra-freq 测量&#xff1a;serving cell SSB的center freq与邻区 SSB的center freq 相同并且两个SSB 的SCS也相同。 2 SSB based inter-freq 测量&#xff1a;serving cell SSB的center freq与邻…

用Qt 对接‌百度语音识别接口

一 、前期准备工作 1&#xff0c;搭建好开发环境&#xff1b; 2&#xff0c;注册百度云平台&#xff0c;获取语音相关东西&#xff0c; 短语音识别标准版_短语音识别-百度AI开放平台 (baidu.com) 3&#xff0c;涉及到的Qt 类有 QAudioFormat&#xff0c;QAudioDeviceInfo&a…

【HarmonyOS NEXT开发】如何设置水平/垂直方向的左/居中/右对齐——RelativeContainer的AlignRules设置

文章目录 【HarmonyOS NEXT开发】如何设置水平/垂直方向的左/居中/右对齐——RelativeContainer的AlignRules设置RelativeContainer 和 AlignRules 的关系AlignRules 语法详解 【HarmonyOS NEXT开发】如何设置水平/垂直方向的左/居中/右对齐——RelativeContainer的AlignRules设…

Cesium 展示——Cesium 初始化视角在中国并加载数据(china.json)

文章目录 需求一:初始化视角在中国分析需求二:加载中国数据(china.json)需求一:初始化视角在中国 在初始化 Cesium 的 Viewer 后,视角是在美国,如何让其视角指向中国 分析 viewer.value = new Cesium.Viewer(cesiumContainer.value, {homeButton

Linux通配符*、man 、cp、mv、echo、cat、more、less、head、tail、等指令、管道 | 、指令的本质 等的介绍

文章目录 前言一、Linux通配符*二、man 指令三、 cp 指令四、mv指令五、 echo 指令六、cat 指令七、more 指令八、 less 指令九、 head 指令十、 tail指令十一、 管道 |十二、指令的本质总结 前言 Linux通配符*、man 、cp、mv、echo、cat、more、less、head、tail、等指令、管…

如何使用 ONNX 结合 GPU 加速推理(CUDA 与 cuDNN 简明指南)

前言 在深度学习模型推理中,使用 GPU 进行加速是提升模型推理速度的关键方式之一。 本文将带大家一步步了解如何使用 ONNX Runtime 结合 NVIDIA 的 CUDA 和 cuDNN 进行 GPU 加速。 一、查找ONNX、CUDA与cuDNN之间的对应版本 首先,我们需要确保 ONNX Runtime 与 CUDA 和 cu…

分类预测|基于差分优化DE-支持向量机数据分类预测完整Matlab程序 DE-SVM

分类预测|基于差分优化DE-支持向量机数据分类预测完整Matlab程序 DE-SVM 文章目录 一、基本原理DE-SVM 分类预测原理和流程总结 二、实验结果三、核心代码四、代码获取五、总结 一、基本原理 DE-SVM 分类预测原理和流程 1. 差分进化优化算法&#xff08;DE&#xff09; 原理…

用于安全研究的 Elastic Container Project

作者&#xff1a;来自 Elastic Andrew Pease•Colson Wilhoit•Derek Ditch 使用 Docker 启动 Elastic Stack 序言 Elastic Stack 是一个模块化数据分析生态系统。虽然这允许工程灵活性&#xff0c;但建立开发实例进行测试可能很麻烦。建立 Elastic Stack 的最简单方法是使用…