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

【力扣 Hot100】滑动窗口巧解字串问题

D13

无重复字符的最长字串

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

这道题目是典型的滑动窗口问题,核心为:

用两个指针leftright维护一个窗口

  • right不断向右扩展,尝试加入新的字符
  • 如果加入字符导致重复,移动left,缩小窗口,直到重复值被除掉。
  • 每次都更新窗口的最大值
class Solution {public int lengthOfLongestSubstring(String s) {char[] chars = s.toCharArray(); //转化为char数组便于操作int left = 0; //窗口左端点int[] cnt = new int[128]; // ASCII字符频率统计(包含全部ASCII字符)int ans = 0; // 记录最大长度for (int right = 0; right < chars.length; right++) {char c = chars[right];cnt[c]++; // 记录某字符的重复次数while(cnt[c] > 1){cnt[chars[left]]--; // 除掉重复值,移动窗口left++;}ans = Math.max(ans, right - left + 1); // 最长重复子串}return ans;}
}

这里需要注意的是,一定是先除掉重复值,再移动left。要先减掉重复值的记数,再移动窗口。否则先移动窗口后,窗口边缘的值已经改变,减去的就是其他字符的记数次数。


定长字串中元音的最大数目

1456. 定长子串中元音的最大数目 - 力扣(LeetCode)

这个题目是一道定长滑窗,介绍一下灵神的套路:

定长滑窗套路

窗口右端点在 i 时,由于窗口长度为 k,所以窗口左端点为 i−k+1。

总结成三步:入-更新-出。

  • 入:下标为 i 的元素进入窗口,更新相关统计量。如果窗口左端点 i−k+1<0,即 i<k−1,则尚未形成第一个窗口,重复第一步。
  • 更新:更新答案。一般是更新最大值/最小值。
  • 出:下标为 i−k+1 的元素离开窗口,更新相关统计量,为下一个循环做准备。

以上三步适用于所有定长滑窗题目。

class Solution {public int maxVowels(String s, int k) {char[] chars = s.toCharArray();int ans = 0;int cnt = 0;for (int i = 0; i < chars.length; i++) {// 入char c = chars[i];if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') cnt++;if(i < k - 1) continue; // 窗口大小不够,还未形成第一个窗口// 更新ans = Math.max(ans, cnt);// 移出左端元素char l = chars[i - k + 1];if(l == 'a' || l == 'e' || l == 'i' || l == 'o' || l == 'u') cnt--;}return ans;}
}

找出字符串中所有字母异位词

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

解答这道题目时建议先看一下上一题定长滑窗的套路,这个题目实际上是找出s中长度为p.length的字串,作为窗口,判断字串的字母是否和p中相同(不考虑各字母的位置)

那么把套路应用到这个题目就是:

前提:对p的统计数组cntP,对s的统计数组cntS

  • 入:从头开始遍历s,记为right,将字母加入到窗口,直到窗口大小与p.length相等,left = right - p.length + 1 > 0
  • 更新:如果cntScntP相等,那么说明窗口与p时字母异位词,记录起始索引left
  • 出:移出cntS[left]

按照这个思路代码如下:

class Solution {public List<Integer> findAnagrams(String s, String p) {int[] cntS = new int[26];int[] cntP = new int[26];char[] pc = p.toCharArray();List<Integer> list = new ArrayList<>();// 记录p的字母出现次数for (char c : pc) {cntP[c - 'a']++;}for (int right = 0; right < s.length(); right++) {// 入cntS[s.charAt(right) - 'a']++; // 填充窗口int left = right - p.length() + 1;if(left < 0) continue;// 更新if(Arrays.equals(cntS, cntP)){list.add(left);}cntS[s.charAt(left) - 'a']--;}return list;}
}

如果这篇文章对你有帮助,请点赞、评论、收藏,创作不易,你的支持是我创作的动力。

http://www.dtcms.com/a/342310.html

相关文章:

  • 鸿蒙中基础耗时分析:Time分析
  • Minecraft 1.18.2 或更高版本(如1.19.2、1.20.1)选择模组mod加载器
  • spark数据缓存机制
  • 在没有客户端的客户环境下,如何用 Python 一键执行 MySQL 与达梦数据库 SQL
  • 【开源项目】边浏览边学外语:开源工具 Read Frog 如何用 AI 重构语言学习
  • Java实战:深度解析SQL中的表与字段信息(支持子查询、连接查询)
  • 粗粮厂的基于flink的汽车实时数仓解决方案
  • Elasticsearch Ruby 客户端elasticsearch / elasticsearch-api
  • 小程序UI(自定义Navbar)
  • 【TrOCR】用Transformer和torch库实现TrOCR模型
  • yggjs_rlayout 科技风主题布局使用教程
  • StarRocks不能启动 ,StarRocksFe节点不能启动问题 处理
  • macos使用FFmpeg与SDL解码并播放H.265视频
  • 【TrOCR】模型预训练权重各个文件说明
  • 从800米到2000米:耐达讯自动化Profibus转光纤如何让软启动器效率翻倍?
  • 表达式(CSP-J 2021-Expr)题目详解
  • Django的生命周期
  • 如何在DHTMLX Scheduler中实现带拖拽的任务待办区(Backlog)
  • 非常飘逸的 Qt 菜单控件
  • logger级别及大小
  • 如何安装和配置W3 Total Cache以提升WordPress网站性能
  • C++设计模式--策略模式与观察者模式
  • 小红书AI落地与前端开发技术全解析(From AI)
  • Python 正则表达式(更长的正则表达式示例)
  • 【基础排序】CF - 赌场游戏Playing in a Casino
  • 机器学习4
  • 精算中的提升曲线(Lift Curve)与机器学习中的差别
  • 网络打印机安装操作指南
  • 健康常识查询系统|基于java和小程序的健康常识查询系统设计与实现(源码+数据库+文档)
  • CentOS7安装部署PostgreSQL