LeetCode 76 最小覆盖子串|JS 滑动窗口标准解法(逐行精讲)
大家好这篇文章用来记录LeetCode 76 最小覆盖子串的 JS 标准解法这道题是滑动窗口的经典必做题面试频率极高。我会直接给出可 AC 代码并逐行详细解释方便自己复习也分享给大家。题目简介给两个字符串s和t找出s中包含t所有字符的最短子串。如果没有返回空字符串。完整可提交代码varminWindowfunction(s,t){constneed{};constwindow{};letvalid0;letleft0,right0;letstart0,lenInfinity;// 统计 t 中每个字符需要的数量for(constcoft){need[c](need[c]||0)1;}// 需要凑齐的字符种类数constneedSizeObject.keys(need).length;// 右指针遍历整个字符串while(rights.length){constcs[right];right;// 如果当前字符是我们需要的if(need[c]){window[c](window[c]||0)1;// 某一类字符数量达标valid1if(window[c]need[c]){valid;}}// 当窗口已经满足所有条件开始收缩左侧while(validneedSize){// 更新最小窗口if(right-leftlen){startleft;lenright-left;}// 准备移除左指针字符constds[left];left;// 如果是需要的字符判断是否会破坏 validif(need[d]){if(window[d]need[d]){valid--;}window[d]--;}}}// 没有找到返回空否则返回截取的子串returnlenInfinity?:s.slice(start,startlen);};逐行详细解析1. 变量定义constneed{};// 记录 t 中每个字符需要多少个constwindow{};// 记录当前窗口里每个字符有多少个letvalid0;// 记录已经“数量达标”的字符种类数letleft0,right0;// 滑动窗口双指针letstart0,lenInfinity;// 记录最终最短子串的起点和长度need我们要找的字符目标数量window当前窗口内的字符数量valid核心判断条件表示有多少种字符已经满足数量要求left/right窗口左、右边界start/len保存最优解避免反复截取字符串2. 统计目标字符for(constcoft){need[c](need[c]||0)1;}constneedSizeObject.keys(need).length;遍历t统计每个字符需要多少个needSize一共需要凑齐多少种字符3. 右指针扩大窗口while(rights.length){constcs[right];right;if(need[c]){window[c](window[c]||0)1;if(window[c]need[c]){valid;}}右指针一直往右走扩大窗口遇到需要的字符就加入window计数当某字符数量刚好达标时valid 14. 左指针收缩窗口核心while(validneedSize){// 更新最小窗口if(right-leftlen){startleft;lenright-left;}constds[left];left;if(need[d]){if(window[d]need[d]){valid--;}window[d]--;}}当valid needSize说明当前窗口已经包含了 t 所有字符这时尽可能缩小窗口寻找更短的子串每次移动左指针前先更新最小窗口记录再把左边字符移出窗口如果移出后导致某字符不满足数量valid--退出循环5. 返回结果returnlenInfinity?:s.slice(start,startlen);如果len还是无穷大说明没找到返回空串否则返回记录的最短子串核心思想总结这道题的核心就是滑动窗口 哈希计数用右指针扩大窗口直到满足条件用左指针收缩窗口直到不满足条件全程记录最小窗口用valid精准判断窗口是否合法这套模板可以通杀绝大多数子串滑动窗口题非常实用。测试用例console.log(minWindow(ADOBECODEBANC,ABC));// BANCconsole.log(minWindow(a,a));// aconsole.log(minWindow(a,aa));//