力扣76 最小覆盖子串 JS Map字典+滑动窗口

76. 最小覆盖子串 - 力扣(LeetCode)

个人感觉:

核心是利用 map 建立一个被包含字符串的字典,并记录好这个被包含字符串中每个元素(键名)出现的次数(键值)。

移动指针遍历,利用 map 的 has 方法,如果遇到被包含字符串中的元素,字典中对应元素的键值做出相应的改变。

当字典中所有键名对应的键值都为 0 时,意味着字符串都被包含了,进行窗口的缩小。

坑:

移动右指针时:只有字典元素对应键值为 0 的时候 ,记录被包含字符串总个数才进行 -1

移动左指针时:只有字典元素对应键值为 1 的时候,记录被包含字符串总个数才进行 +1

var minWindow = function (s, t) {
    // 把被涵盖的字符串转成字典,把每个元素的初始键值都设置为 1
    // 转换成字典 可以利用 has 方法便捷的判断是否存在(被包含)
    let map = new Map();
    for (let i = 0; i < t.length; i++) {
        map.set(t[i], map.has(t[i]) ? map.get(t[i]) + 1 : 1);
    }
    // 初始化左右指针
    let left = 0;
    let right = 0;
    // 最终最小覆盖字串的结果
    let res = '';
    // 判定被覆盖字符串是否都被包含了
    let sum = map.size;
    while (right < s.length) {
        if (map.has(s[right])) {
            map.set(s[right], map.get(s[right]) - 1);
            // 当字典中某个元素多次出现的时候,这个元素的键值是可以减成负数的
            // 第一个坑:当字典中键值为 0 的时候 sum才进行-- 
            if(map.get(s[right]) === 0) sum--;
        }
        while (sum === 0) {
            let newRes = s.substring(left, right + 1);
            if(!res || res.length > newRes.length) res = newRes;
            if (map.has(s[left])) {
                map.set(s[left], map.get(s[left]) + 1);
                // 第二个坑:只有当字典中键值为 1 时 sum才进行++
                // 因为之前字典中元素对应的键值是可能为负数的
                if(map.get(s[left]) === 1) sum++;
            }
            left++;
        }
        right++;
    }
    return res;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值