news 2026/4/16 8:48:49

双指针专题(七):覆盖所有需求的最小代价——「最小覆盖子串」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
双指针专题(七):覆盖所有需求的最小代价——「最小覆盖子串」

这道题是Hard级别,也是无数面试者的噩梦。 前面的题(水果成篮、无重复子串)都是窗口**“大了才缩”。 这道题反过来:窗口“不够大(没凑齐)就一直扩,一旦凑齐了就拼命缩”,试图找到最小**的那个解。

力扣 76. 最小覆盖子串

https://leetcode.cn/problems/minimum-window-substring/

题目分析:

  • 输入:字符串s(资源池), 字符串t(需求清单)。

  • 目标:在s中找到一个最短的子串,包含t中所有的字符(包括重复字符,比如t="AA", 子串里也得有两个A)。

  • 输出:这个最短子串。如果不存在,返回空字符串。

例子:s = "ADOBECODEBANC",t = "ABC"

  1. 一直扩:窗口一直向右,直到变成ADOBEC。此时包含了 A, B, C。这是一个可行解,但太长了。

  2. 尝试缩:左边A移出去?不行,A 也是必须的。

  3. 继续跑:...直到找到BANC,包含 A, B, C,且长度只有 4。

核心思维:两个哈希表 + 有效计数器

这道题单纯用 Map 会比较乱,我们需要维护两个概念:

  1. needMap:记录t中每个字符需要多少个。 (比如A:1, B:1, C:1)

  2. windowMap:记录当前窗口里已经有多少个字符。

  3. valid变量:记录有多少个字符已经**“达标”**了。

    • 比如t需要A1个。当窗口里A的数量从 0 变成 1 时,valid++

    • valid等于need.size时,说明所有种类的字符都凑齐了!

操作逻辑:

  1. 进窗口 (right)

    • 读字符,更新windowMap。

    • 如果window[c] === need[c],说明这个字符凑够了,valid++

  2. 收缩窗口 (left)

    • While (valid === need.size):只要凑齐了,就一直缩!

      • 更新结果:如果当前窗口更短,记录下来。

      • 踢出字符:把s[left]移出窗口。

      • 关键判断:如果移出的字符导致window[c] < need[c],说明不再达标了,valid--

      • left++

代码实现 (JavaScript)

JavaScript

/** * @param {string} s * @param {string} t * @return {string} */ var minWindow = function(s, t) { // 1. 统计需求 t const need = new Map(); for (const c of t) { need.set(c, (need.get(c) || 0) + 1); } const window = new Map(); let left = 0, right = 0; let valid = 0; // 记录有多少种字符已经满足要求了 // 记录最小子串的起始位置和长度 let start = 0; let minLen = Infinity; while (right < s.length) { // --- 进窗口 --- const c = s[right]; right++; // 右指针移动 // 如果这个字符是我们需要关注的 if (need.has(c)) { window.set(c, (window.get(c) || 0) + 1); // 如果窗口里的数量刚刚好达到了需求,valid + 1 if (window.get(c) === need.get(c)) { valid++; } } // --- 出窗口 --- // 当 valid 等于 need 的大小时,说明所有字符都凑齐了 // 这时候开始尝试收缩左边界,寻找“最小” while (valid === need.size) { // 更新最小覆盖子串 if (right - left < minLen) { start = left; minLen = right - left; } // 准备移出左边的字符 const d = s[left]; left++; // 如果移出的字符是我们需要关注的 if (need.has(d)) { // 如果移出前,数量刚好达标。那移出后肯定就不达标了 if (window.get(d) === need.get(d)) { valid--; } window.set(d, window.get(d) - 1); } } } return minLen === Infinity ? "" : s.substr(start, minLen); };

深度辨析:为什么是window.get(c) === need.get(c)

  • 假设t = "AA",s = "AAAA"

  • need = {A: 2}

  • right读第一个 A:window={A:1}。不等于 2,valid 不变。

  • right读第二个 A:window={A:2}。等于 2!valid++(A 达标了)。

  • right读第三个 A:window={A:3}。不等于 2,valid 不变。

  • 结论valid只在“刚刚好满足”的那一瞬间增加。这保证了即使窗口里有 100 个 A,valid也只算一次。

总结

拿下这道题,不定长滑动窗口这一块你就彻底毕业了。 它的模板是所有滑动窗口里最全的:

  1. Map 统计需求。

  2. valid变量判断状态。

  3. while(valid === target)进行收缩优化。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 9:39:13

表单上传总失败?,深度剖析PyWebIO文件上传常见坑及避坑方案

第一章&#xff1a;表单上传失败的常见现象与背景在现代Web应用开发中&#xff0c;文件上传是用户与系统交互的重要功能之一&#xff0c;广泛应用于头像设置、文档提交和媒体资源管理等场景。然而&#xff0c;表单上传失败是开发者频繁遇到的问题&#xff0c;其表现形式多样&am…

作者头像 李华
网站建设 2026/4/15 11:19:40

X射线检测技术:多领域关键应用与性能发展趋势解析

X射线检测技术&#xff0c;是一种成熟的无损检测的手段&#xff0c;它在工业领域发挥着不可替代的作用&#xff0c;它在食品领域发挥着不可替代的作用&#xff0c;它在安检等多个关键领域发挥着不可替代的作用&#xff0c;其核心原理在于利用X射线穿透物质&#xff0c;由于物质…

作者头像 李华
网站建设 2026/4/13 9:04:19

AI排名优化技术解析:原理、服务商与应用场景

于当下数字化营销的环境里头&#xff0c;AI排名优化已然成了企业用以提升在线可见度以及获取精准流量的关键技术办法&#xff0c;此技术主要借由算法去剖析搜索引擎跟内容平台的排名机制&#xff0c;联合语义理解呀、用户意图识别还有实时数据反馈&#xff0c;针对特定关键词或…

作者头像 李华
网站建设 2026/4/14 20:07:21

导师推荐9个AI论文写作软件,专科生轻松搞定毕业论文!

导师推荐9个AI论文写作软件&#xff0c;专科生轻松搞定毕业论文&#xff01; AI 工具如何助力论文写作&#xff0c;让专科生轻松应对毕业挑战 在当前教育环境中&#xff0c;越来越多的专科生面临毕业论文的撰写压力。面对复杂的格式要求、繁重的文献查阅以及反复的修改过程&…

作者头像 李华
网站建设 2026/4/14 17:22:08

2025空间智能技术大爆发

2025年超图技术&#xff0c;空间智能软件技术的进化与深耕 这篇文章是关于2025年空间智能软件技术的进化与深耕的技术合集&#xff0c;重点介绍了SuperMap GIS 2025在多个领域的技术突破和应用创新。以下是文章的主要内容&#xff1a; 地理空间AI 技术突破&#xff1a;2…

作者头像 李华
网站建设 2026/4/10 9:33:19

MyBatisPlus是否可用于存储VoxCPM-1.5-TTS的语音日志数据?

MyBatisPlus 是否可用于存储 VoxCPM-1.5-TTS 的语音日志数据&#xff1f; 在构建 AI 驱动的语音服务时&#xff0c;一个常被忽视但至关重要的环节是——如何高效、可靠地管理生成过程中的各类数据。比如&#xff0c;当用户通过网页输入一段文字&#xff0c;系统调用 VoxCPM-1.5…

作者头像 李华