【JS力扣刷题笔记】76. 最小覆盖子串

这是跟着代码随想录的顺序学习算法的第?天。(二刷)

以下是学习时自己的一些理解与笔记,如有错误欢迎指正与讨论。


76. 最小覆盖子串

参考相关链接:

76. 最小覆盖子串


笔记

解本题的主要方法是,滑动窗口 + Map

主要思路:

  • left、right 记录当前窗口的两端

  • map 记录 t 中各个字符的被覆盖情况,即键名为每个字符 ,对应的键值为 目前滑动窗口中覆盖 t 所需要的该字符的数量 ,这意味着键值是有可能出现负数的情况,具体表示的含义就是当前滑动窗口中关于该字符的数量是有多余的(也就是数量足够覆盖 t 的对应字符,且有多余)

  • temp 用于记录 t 的未被覆盖的字符数量

  • res 用于记录结果


  • 扩大滑动窗口,即移动 right ,并进行判断,如果 s[right]t 所需要的字符,则变化对应的 map 的键值,

    并根据当前的字符是否为多余的map.get(s[right]) > 0 则不是多余的),来改变 temp 的大小。

  • 当滑动窗口中的字符串足以覆盖 t 时候(即 temp === 0 ),收缩 left 直到当前的滑动窗口不足以覆盖 t 即(即 temp > 0 ),值得一提的是,这里的 temp 在多余的字符串数量发生变化时,不做改变。

  • 收缩时,根据需要 res[1] - res[0] > right - left ,记录当前的滑动窗口两端的值 [res[0], res[1]] = [left, right]

  • 最后,根据 res 记录的滑动窗口情况,返回对应的结果。

/**
 * @param {string} s
 * @param {string} t
 * @return {string}
 */
var minWindow = function(s, t) {
    // s 中 涵盖 t 所有字符的 最小子串
    // 否则 返回 ""
    
    // map中的每个值都小于 0
    // 记录是否满足 
    // 从正数减小才算数

    const map = new Map();
    let left = 0, right = 0, temp = t.length, res = [0, Infinity];
    for(const x of t) { // 记录 t 各字母的数量
        if(map.has(x)) {
            map.set(x, map.get(x) + 1);
        } else {
            map.set(x, 1);
        }
    }

    for(; right < s.length; right++) {
        // 填入 s[right]
        if(map.has(s[right])) {
            // 该字母未填满
            if(map.get(s[right]) > 0) {
                temp--;
            }
            map.set(s[right], map.get(s[right]) - 1);
        } else continue;

        // 未填满 t 继续填

        // 填满 t 减长度 移动 left 直到 temp > 0
        while(temp === 0 && left <= right) {
            // 记录最短覆盖子串
            if(res[1] - res[0] > right - left) {
                [res[0], res[1]] = [left, right];
            }
            if(map.has(s[left])) {
                // 该字母无多余数量 即 大于等于 0
                if(map.get(s[left]) >= 0) {
                    temp++;
                }
                map.set(s[left], map.get(s[left]) + 1);
            }
            left++;
        }
    }

    return res[1] === Infinity ? "" : s.slice(res[0], res[1] + 1);
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值