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

【Hot100】滑动窗口

这一类的核心思想是:维护一个动态的窗口 [left, right]

  1. 扩张right 指针不断向右移动,将新元素纳入窗口。
  2. 收缩:当窗口内的数据满足特定条件(如和达标、出现重复、覆盖所有字符)时,尝试移动 left 指针缩小窗口,以寻找更优解(最短长度)或维持合法性。
  3. 状态维护:通常需要一个变量(如 sum)或数据结构(如 HashMap/数组)来实时记录窗口内的状态。

📝 本类题型总结

题目 窗口特性 关键差异点 (vs 长度最小子数组)
209. 最小长度子数组 动态伸缩 基准sum >= targetwhile 收缩,求 min
3. 无重复最长子串 动态伸缩 状态用 Map 记频次。收缩条件:出现重复。求 max
76. 最小覆盖子串 动态伸缩 valid 计数匹配 need。收缩条件:完全覆盖。需记录 startlen 返回子串。
438. 找异位词 固定大小 窗口大小固定为 p.length()无需 while 收缩,每次只移一步。收集所有合法的 left 索引。

🏆 母题:LeetCode 209. 长度最小的子数组 (Minimum Size Subarray Sum)

题目内容:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 ,并返回其长度。如果不存在符合条件的子数组,返回 0
核心逻辑

  1. right 扩张,累加 sum
  2. 一旦 sum >= target,进入 while 循环:更新最小长度,然后 left 右移并减去对应值,直到 sum < target
  3. 这是一个典型的 “求最小长度” 问题。
class Solution {public int minSubArrayLen(int target, int[] nums) {int left = 0;int sum = 0;int result = Integer.MAX_VALUE; // 初始化为最大值for (int right = 0; right < nums.length; right++) {sum += nums[right]; // 1. 扩张窗口// ⚠️ [核心逻辑] 2. 当窗口和满足条件时,尝试收缩左边界以寻找更小长度while (sum >= target) {result = Math.min(result, right - left + 1);sum -= nums[left];left++;}}return result == Integer.MAX_VALUE ? 0 : result;}
}

🔄 变体 1:LeetCode 3. 无重复字符的最长子串 (Longest Substring Without Repeating Characters)

题目内容:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
相比母题的变化

  1. 状态结构:母题用 int sum;本题需要用 Map<Character, Integer>int[128] 数组来记录字符出现的频次
  2. 收缩条件:母题是 sum >= target;本题是 当前字符频次 > 1(即出现了重复)。
  3. 结果目标:母题求 min;本题求 max(最长长度)。
  4. 收缩逻辑:只要窗口内有重复,就一直收缩 left 直到该重复字符频次降为 1。
import java.util.HashMap;
import java.util.Map;class Solution {public int lengthOfLongestSubstring(String s) {Map<Character, Integer> window = new HashMap<>();int left = 0;int result = 0; // ⚠️ [变化点 1] 结果初始化为 0,求最大值for (int right = 0; right < s.length(); right++) {char c = s.charAt(right);window.put(c, window.getOrDefault(c, 0) + 1);// ⚠️ [变化点 2] 收缩条件:当当前字符重复时 (频次 > 1)// 母题是 sum >= target,这里是 window.get(c) > 1while (window.get(c) > 1) {char leftChar = s.charAt(left);window.put(leftChar, window.get(leftChar) - 1);left++;}// ⚠️ [变化点 3] 更新结果:求最大长度// 母题是在 while 内部更新 min,这里是在 while 结束后(窗口合法时)更新 maxresult = Math.max(result, right - left + 1);}return result;}
}

🔄 变体 2:LeetCode 76. 最小覆盖子串 (Minimum Window Substring)

题目内容:给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""
相比母题的变化

  1. 双 Map 结构:需要 need 地图记录 t 的要求,window 地图记录当前窗口状态。
  2. 有效计数 valid:引入变量 valid 记录窗口中满足 need 要求的字符个数
  3. 收缩条件:当 valid == need.size() 时,说明窗口已覆盖所有字符,开始收缩以求最小。
  4. 结果记录:需要记录最佳子串的 起始索引 start长度 len,最后截取字符串。
import java.util.HashMap;
import java.util.Map;class Solution {public String minWindow(String s, String t) {Map<Character, Integer> need = new HashMap<>();Map<Character, Integer> window = new HashMap<>();for (char c : t.toCharArray()) {need.put(c, need.getOrDefault(c, 0) + 1);}int left = 0, right = 0;int valid = 0; // ⚠️ [变化点 1] 新增有效字符计数器int start = 0, len = Integer.MAX_VALUE; // ⚠️ [变化点 2] 记录最佳子串位置while (right < s.length()) {char c = s.charAt(right);right++;if (need.containsKey(c)) {window.put(c, window.getOrDefault(c, 0) + 1);// 只有当某个字符的数量刚好满足需求时,valid 才 +1if (window.get(c).equals(need.get(c))) {valid++;}}// ⚠️ [变化点 3] 收缩条件:当有效字符数满足 t 的所有要求while (valid == need.size()) {// 更新最优解if (right - left < len) {start = left;len = right - left;}char d = s.charAt(left);left++;if (need.containsKey(d)) {// 如果移出的字符导致不再满足需求,valid -1if (window.get(d).equals(need.get(d))) {valid--;}window.put(d, window.get(d) - 1);}}}return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);}
}

🔄 变体 3:LeetCode 438. 找到字符串中所有字母异位词 (Find All Anagrams in a String)

题目内容:给定两个字符串 sp,找到 s 中所有 p异位词 的子串,返回这些子串的起始索引。
相比母题的变化

  1. 固定窗口大小:异位词长度必须等于 p.length()。所以窗口大小是固定的。
  2. 收缩策略:不需要 while 循环收缩。每次 right 移动后,如果窗口大小超过 p.length()只移动 left 一次 即可维持固定大小。
  3. 结果收集:每当 valid == need.size() 且窗口大小正确时,记录 left 索引到列表。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;class Solution {public List<Integer> findAnagrams(String s, String p) {List<Integer> result = new ArrayList<>();if (s.length() < p.length()) return result;Map<Character, Integer> need = new HashMap<>();Map<Character, Integer> window = new HashMap<>();for (char c : p.toCharArray()) {need.put(c, need.getOrDefault(c, 0) + 1);}int left = 0, right = 0;int valid = 0;while (right < s.length()) {char c = s.charAt(right);right++;if (need.containsKey(c)) {window.put(c, window.getOrDefault(c, 0) + 1);if (window.get(c).equals(need.get(c))) {valid++;}}// ⚠️ [变化点 1] 维护固定窗口大小:当窗口大小 > p.length() 时,收缩左边// 母题是 while 循环直到不满足条件,这里只需要 if 或者 while 控制大小为 p.length()if (right - left >= p.length()) {// 在收缩前,先判断当前窗口是否满足条件(因为此时窗口大小正好是 p.length())// 注意:这里判断时机很关键,通常在收缩前判断,或者在收缩后判断下一轮// 更清晰的逻辑:当窗口大小达到 p.length() 时检查if (valid == need.size()) {result.add(left);}// 开始收缩:移出左边元素char d = s.charAt(left);left++;if (need.containsKey(d)) {if (window.get(d).equals(need.get(d))) {valid--;}window.put(d, window.get(d) - 1);}}}return result;}
}

(注:438题的代码逻辑中,判断 valid 的时机也可以放在收缩之后,取决于 right 是先加还是后加,上述代码采用的是“达到长度即检查,然后收缩”的逻辑,确保每次检查时窗口长度均为 p.length())

http://www.jsqmd.com/news/446654/

相关文章:

  • 分期乐购物额度怎么回收?让您了解的方法实在靠谱 - 容易提小溪
  • 2026评测:推荐的检查井公司优势在哪?3米水泥管/钢承口水泥管/阀门井/预制水泥管/混凝土阀门井,井厂家推荐 - 品牌推荐师
  • HarmonyOS智慧农业管理应用开发教程--高高种地--第29篇:数据管理与备份 - 详解
  • 定稿前必看!继续教育降重神器 —— 千笔AI
  • 好用还专业! 继续教育降重神器 —— 千笔·专业降AI率智能体
  • 一文搞懂零拷贝(Zero-Copy)技术
  • 深入解析:【Ranger】Ranger Admin 配置 Knox 策略时出现,the trustAnchors parameter must be non-empty
  • 权威专利申请平台盘点,为您的创意保驾护航,专利代写/专利改写润色/智能专利分析/智能专利查重,专利申请器怎么选择 - 品牌推荐师
  • 为什么回收微信立减金,老用户都选这家? - 京顺回收
  • [canvas/WebGL]
  • 茶吧机装配标准要求
  • Spring原理
  • 4B小模型干翻70B?CoVe用约束验证让工具调用Agent数据效率提升18倍
  • FastAPI - Study Notes 4
  • 完整教程:机器学习不平衡数据处理三招:k折交叉验证、下采样与过采样实战
  • LeetCode1888:使二进制字符串交替的最少反转次数
  • Comsol超表面技术驱动下的光学双稳态现象研究
  • 互联网企业如何通过Vue.js实现多平台文件夹的目录结构秒传与分享?
  • 机械制造企业如何用JavaScript优化大文件夹分片上传的内存占用?
  • CF923A题解
  • 达梦数据库性能优化技术指南
  • 达梦数据库的常用操作
  • 双驱价值重构法:破解商务衬衫效率痛点的独家解决方案 - 速递信息
  • 欧拉ie大纲
  • selenium运用(窗口)
  • Codex 输出乱码 - Higurashi
  • 简单理解:STM32CubeMX NVIC 配置界面
  • 工程建筑行业如何通过Vue3集成WebUploader实现CAD文件夹的断点续传?
  • 2025-2026年度3000-5000元价位段智能马桶综合实力权威TOP榜 - charlieruizvin
  • 2月精选!手拉式气动葫芦厂家推荐与产品特色,12吨气动葫芦/大吨位气动葫芦/小车式气动葫芦,手拉式气动葫芦供应商如何选 - 品牌推荐师