当前位置: 首页 > news >正文

滑动窗口题目总结(持续更新中)

变长滑动窗口

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

给定一个字符串,维护一个窗口,满足窗口内的字符不重复,输出窗口的最长长度。注意的是本题窗口右侧(又名右区间)每次移动一位,而对于窗口左侧(左区间),当右区间碰到重复字符时,将左区间移动到该重复字符上一次出现的索引位置的下一位来保证窗口中字符不重复。

class Solution {public int lengthOfLongestSubstring(String s) {int l = 0, r = 0;int n = s.length();// k表示字符,v表示其最近一次出现的索引位置Map<Character, Integer> map = new HashMap<>();int maxLen = 0;while(r < n) {// 当前右区间新进来的字符tchar t = s.charAt(r);if(map.containsKey(t)) {// 重复了,更新左区间,左区间移动到该重复字符上一次出现的索引位置的下一位l = Math.max(l, map.get(t) + 1);}// 更新/添加字符t的索引位置为rmap.put(t, r);// 此时窗口长度是否更大,如果更大就更新maxLen = Math.max(maxLen, r - l + 1);// 右区间移动一位++r;}return maxLen;}
}

2.替换后的最长重复子串

给定一个字符串,维护一个窗口,满足如果窗口长度-最高频字符数量不大于k,输出满足要求的窗口的最长长度。注意的是本题窗口右侧每次移动一位,而对于窗口左侧(左区间),当窗口长度-最高频字符数量大于k,那么就需要移动一位。

class Solution {public int characterReplacement(String s, int k) {int l = 0, r = 0, n = s.length();// 记录窗口内各字符频次int[] cnt = new int[26];int maxLen = 0, maxF = 0;;while(r < n) {char t = s.charAt(r);++cnt[t - 'A'];// 维护窗口的最高频字符的数量maxF = Math.max(maxF, cnt[t - 'A']);// 如果窗口长度-最高频字符数量大于k,那么说明即使k次替换也不行,需要移动左区间了if(r - l + 1 - maxF > k) {--cnt[s.charAt(l) - 'A'];// 左区间右移一步++l;}maxLen = Math.max(maxLen, r - l + 1);// 右区间右移一步++r;}return maxLen;}
}

3.考试的最大困扰度

这题和2.替换后的最长重复子串不能说很像,只能说一模一样。那一题的字符串是由大写英文字符组成,这题是只由T和F组成。然后本质还是求替换后的最长重复子串。

class Solution {public int maxConsecutiveAnswers(String answerKey, int k) {int n = answerKey.length();int[] arr = new int[n];for(int i = 0; i < n; i++) {if(answerKey.charAt(i) == 'T') {arr[i] = 0;} else {arr[i] = 1;}}int[] cnt = new int[2];int l = 0, r = 0;int maxFrW = 0, maxLen = 0;while(r < n) {// 字符频次更新++cnt[arr[r]];// 更新该窗口的最高频次字符数量maxFrW = Math.max(maxFrW, cnt[arr[r]]);if(r - l + 1 - maxFrW  > k) {// 左区间右移一位--cnt[arr[l]];++l;}// 右区间右移一位maxLen = Math.max(maxLen, r - l + 1);++r;}return maxLen;}
}

4.找到字符串中所有字母异位体

给定一个字符串,维护一个窗口,满足窗口内的子字符串是给定字符串的字母异位体,输出所有满足要求的窗口的左侧(/起始)索引。注意的是本题窗口右侧每次移动一位,而对于窗口左侧(左区间),当窗口长度等于给定字符串且是其字母异位体时,那么就需要右移动一位。

class Solution {public List<Integer> findAnagrams(String s, String p) {int m = s.length(), n = p.length();int[] target = new int[26];for(int i = 0; i < n; i++) {++target[p.charAt(i) - 'a'];}int[] cur = new int[26];List<Integer> res = new ArrayList<>();int l = 0, r = 0;while(r < m) {// 取出当前右区间字符char t = s.charAt(r);// 当前窗口的各字符出现次数++cur[t - 'a'];if(r - l + 1 == n) {// 长度一样且是异位词if(isSame(cur, target)) {res.add(l);}// 左窗口移动一位--cur[s.charAt(l) - 'a'];++l;}// 右窗口移动一位++r;}return res;}public boolean isSame(int[] cur, int[] target) {int n = target.length;for(int i = 0; i < n; i++) {if(cur[i] != target[i]) {return false;}}return true;}
}

定长滑动窗口

1.字符串的排列

假设s1的长度为m,那么维持一个长度为m的窗口,找到是否有窗口满足其中的数是s1的排列。

class Solution {public boolean checkInclusion(String s1, String s2) {int m = s1.length(), n = s2.length();if(m > n) {return false;}int[] c1 = new int[26];int[] c2 = new int[26];for(int i = 0; i < m; i++) {++c1[s1.charAt(i) - 'a'];++c2[s2.charAt(i) - 'a'];}if(isSame(c1, c2)) {return true;}// 维持一个定长(长度为m)的滑动窗口for(int r = m; r < n; r++) {// 窗口保持右移遍历,直到满足条件--c2[s2.charAt(r - m) - 'a'];++c2[s2.charAt(r) - 'a'];if(isSame(c1, c2)) {return true;}}return false;}public boolean isSame(int[] cur, int[] target) {int n = target.length;for(int i = 0; i < n; i++) {if(cur[i] != target[i]) {return false;}}return true;}
}

2.可获得的最大点数

假设cardPoints的长度为n,那么维持一个长度为n-k的窗口,找到窗口中数字和最小的窗口,那么除去窗口外的其他点数和就是可获得的最大点数。

class Solution {public int maxScore(int[] cardPoints, int k) {int zsum  = Arrays.stream(cardPoints).sum();int n = cardPoints.length;int ws = n - k;// 维持一个长度为n-k的滑动窗口,找到窗口内和最小的int minSum = 0, sum = 0;for(int i = 0; i < ws; i++) {minSum += cardPoints[i];sum += cardPoints[i];}// 窗口整体右移for(int i = ws; i < n; i++) {sum -= cardPoints[i - ws];sum += cardPoints[i];minSum = Math.min(minSum, sum);}return zsum - minSum;}
}

相关文章:

  • 变长子网划分问题的二叉树解法
  • windows安装composer并更换国内镜像
  • faiss-gpu安装失败
  • 向量以及矩阵
  • 【Unity】XML文件的解析和生成
  • 建造者模式(创建型)
  • 网络安全-学习手册
  • 蓝牙耳机仓设计的单芯片解决方案
  • 信息的浏览
  • 002.文件管理
  • MongoDB备份与恢复以及导入导出
  • C#中数组、ArrayList与List对象的区别及使用场景
  • Windows系统中搭建docker (ubuntu,Docker-desktop)
  • JUNIT使用和注意、以及断言的介绍使用、SpringBoot Test测试类的使用、maven配置使用junit详细介绍
  • pipeline + node +jenkins+kubernetes部署yarn前端项目
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【译】理解JavaScript:new 关键字
  • Computed property XXX was assigned to but it has no setter
  • conda常用的命令
  • javascript从右向左截取指定位数字符的3种方法
  • JavaWeb(学习笔记二)
  • linux安装openssl、swoole等扩展的具体步骤
  • vue学习系列(二)vue-cli
  • WebSocket使用
  • windows-nginx-https-本地配置
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 创建一个Struts2项目maven 方式
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 给初学者:JavaScript 中数组操作注意点
  • 后端_MYSQL
  • 警报:线上事故之CountDownLatch的威力
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • #、%和$符号在OGNL表达式中经常出现
  • #宝哥教你#查看jquery绑定的事件函数
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (一)插入排序
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转)mysql使用Navicat 导出和导入数据库
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .Net mvc总结
  • .NET 中让 Task 支持带超时的异步等待
  • .net6+aspose.words导出word并转pdf
  • .net与java建立WebService再互相调用
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @Bean, @Component, @Configuration简析
  • [Angular 基础] - 表单:响应式表单
  • [AR Foundation] 人脸检测的流程
  • [BZOJ 4034][HAOI2015]T2 [树链剖分]