题解 | #最小覆盖子串#

最小覆盖子串

https://www.nowcoder.com/practice/c466d480d20c4c7c9d322d12ca7955ac

如何利用滑动窗口寻找最小覆盖子串?

  • 利用双指针实现一个滑动窗口,初始时左右指针都指向数组开头,开始寻找时右指针开始移动,直到满足某个条件时停下,此时左右指针构造的滑动窗口就满足了题目条件所需内容。为了进一步达到最小条件要求,需要移动左指针缩小窗口,直到不满足条件时,再移动右指针寻找满足条件的窗口,直到右指针达到数组末尾,每次达到满足条件的窗口时,都更新所要求的最值状态。
  • 本题初始时左右指针指向S的字符串开头,右指针移动寻找能够覆盖T字符串中所有字符的窗口,如果找到后,则更新当前窗口为最小覆盖子串,为了得到全局最小覆盖子串,需要再移动左指针缩小窗口使窗口中不能覆盖T字符串中的所有字符,此时右指针再继续移动寻找下一个能够覆盖T字符串中所有字符的窗口,并更新最小覆盖子串,直到右指针达到S字符串的末尾。

如何利用哈希表快速判断某个元素是否出现过?

  • 需要维护两个哈希表,键为字符串T中的字符,值为该字符的出现次数,其中一个哈希表保存T字符串中所有字符的出现次数,另一个哈希表保存滑窗中T字符串中所有字符的出现次数。
  • 初始时遍历T中的所有字符,将各字符的出现次数统计在哈希表中,然后遍历S字符串的滑窗,看里面的字符是否在T的哈希表中,如果在说明该字符是T中的字符,所以要在滑窗哈希表中统计该字符的出现次数。由于一个字符可能出现多次,因此只有当两个哈希表中的字符出现次数相等时,才能认为滑窗中完全包含了该字符,此时增加一个字符计数。当字符计数达到T中的字符种类数时,说明此时滑窗中已经包含全部T中的字符了,此时要缩小窗口,更新最小覆盖子串。
  • 滑窗中出现T中的字符时都会计数,在达到T中的该字符个数时增加字符种类,但之后还是可能再遇到该字符,仍然进行计数,也就是滑窗中出现T的字符可能会超过T中该字符的个数,所以在缩小窗口时,只有该字符数量减少到和T中该字符数量相等时,才能认为滑窗中不包含该字符,此时减少滑窗中的该字符种类计数。

参考

https://blog.nowcoder.net/n/1a15814e64704bdfa8349586356e63f1?f=comment

https://blog.nowcoder.net/n/a8b8988da1564ca2b309449ca79dc018?f=comment

/*
 * @Author: LibraStalker **********
 * @Date: 2023-04-24 22:17:18
 * @FilePath: BM90-最小覆盖子串.js
 * @Description: 
 */

/**
  * 
  * @param S string字符串 
  * @param T string字符串 
  * @return string字符串
  */
function minWindow( S ,  T ) {
    // write code here
    const T_hashCount = {};  // 统计T中每个字符的数量
    const S_hashCount = {};  // 统计滑窗中出现T中的字符的数量

    for (let i = 0; i < T.length; ++i) {
        if (T_hashCount.hasOwnProperty(T[i])) {
            T_hashCount[T[i]]++;  // T中可能有重复的字符,每出现一个计数一次
        }
        else {
            T_hashCount[T[i]] = 1;
        }
    }
    for (let i = 0; i < T.length; ++i) {
        S_hashCount[T[i]] = 0;
    }

    let minLength = Infinity;
    let left = 0;
    let right = 0;
    let count = 0;  // 判断滑窗中是否包含了T中所有字符的种类和个数
    let resString = "";

    while (right < S.length) {
        if (T_hashCount.hasOwnProperty(S[right])) {  // 说明S[right]是T中的字符
            S_hashCount[S[right]]++;
            if (S_hashCount[S[right]] === T_hashCount[S[right]]) {  // 如果滑窗中出现的T中的字符达到T中该字符的数量,则这个滑窗包含了这个字符
                ++count;
            }
        }

        ++right;
        while (count === Object.keys(T_hashCount).length) {
            if ((right - left) <= minLength) {
                minLength = right - left;
                resString = S.substring(left, right);
            }

            if (T_hashCount.hasOwnProperty(S[left])) {
                if (S_hashCount[S[left]] === T_hashCount[S[left]]) {  // 如果滑窗中出现的T中的字符达到T中该字符的数量,则这个滑窗包含了这个字符
                    --count;
                }
                S_hashCount[S[left]]--;
            }
            ++left;  // 缩小窗口直至不完全包含T中的全部字符
        }
        
    }

    return resString;
}

module.exports = {
    minWindow : minWindow
};

全部评论

相关推荐

10-25 23:12
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务