当前位置: 首页 > 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.xdnf.cn/news/1342423.html

相关文章:

  • 新的 SHAMOS MacOS 窃取程序利用单行终端命令攻击用户
  • 开发者中使用——控制台打印数据
  • Linux mmap内存映射
  • tail -f与less的区别
  • 【系统信息相关】datecal命令
  • 使用 TensorBoardX 实现 PyTorch 神经网络可视化:从入门到进阶
  • 【运维进阶】Shell 变量
  • VASPKIT模版INCAR笔记
  • 同题异构解决leetcode第3646题下一个特殊回文数
  • Effective C++ 条款55:熟悉Boost库
  • 2025-08-21 Python进阶2——数据结构
  • imx6ull-驱动开发篇33——platform 平台驱动模型
  • C++ this 指针
  • 分治思想在系统分流削峰中的实践与Golang前沿实现
  • Python读取和设置PNG图片的像素值
  • MFC随笔—不使用对话框资源模板创建对话框
  • Effective C++ 条款54:熟悉标准库
  • 【lucene】lucene常用查询一览
  • python 项目编号 2025821 有关于中英文数据的收集、处理
  • 数据结构之排序大全(3)
  • Python数据可视化利器:Matplotlib从入门到实战全解析
  • C ++代码学习笔记(一)
  • TDengine IDMP 运维指南(常见问题)
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(18):文法+单词第6回1
  • 虚幻基础:曲线
  • 基于STM32单片机的二维码识别物联网OneNet云仓库系统
  • 图--常见面试问题
  • 从源码中学习Java面向对象的多态
  • 多级缓存一致性矩阵:ABP vNext 下的旁路 / 写穿 / 写回组合实战
  • MiniGPT-4