Bootstrap

leetcode76-最小覆盖子串

leetcode 76

在这里插入图片描述
本题也是利用滑动窗口来解决,利用哈希表来记录t中每个字符的数量匹配,大于0表示缺少,小于0表示过剩,todo来记录总共还缺少的字母数量。
假设t = aabc,初始时t = 4,需要4个字母,map{a=>2,b=>1,c=>1}。如果匹配到了一个b,那么todo就要减少todo = 3,map{a=>2,b=>0,c=>1},下次再匹配到b,此时todo不需要减少,因为b已经是0,也就是说b已经被覆盖了,当前需要的是a和c,所以todo不改变,因为map是记录在窗口内每个字母出现的频次,所以只要匹配到这个字符是t内的字符都要变更记录map{a=>2,b=>-1,c=>1}

var minWindow = function (s, t) {
    if(s.length < t.length) return "";
    let todo = t.length; // 记录还差多少个字母
    let map = frequencyMap(t);
    let slow = 0; // 左滑窗
    let result;
    for (let i = 0; i < s.length; i++) {
        const item = s[i];
        if (map.has(item)) { // 需要的字母
            if (map.get(item) > 0) { // 判断此字母是否还缺少
                todo--;
            }
            // 更新字母频次
            map.set(item, map.get(item) - 1);
            while (todo === 0) { // 覆盖所有子串,左窗口滑动缩小范围
                // 记录最小子串
                let ans = s.slice(slow, i + 1);
                if (!result || ans.length <= result.length) {
                    result = ans
                }
                if(map.has(s[slow])){
                    map.set(s[slow],map.get(s[slow])+1);
                    if(map.get(s[slow]) > 0){
                        todo++
                    }
                }
                slow++
            }
        }
    }
    return result || "";
};
// 记录每个字母需要出现的频数
function frequencyMap(s){
    const map = new Map();
    for (const item of s) {
        map.set(item, (map.get(item) || 0) + 1);
    }
    return map;
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;