76.最小覆盖子串

image-20210426211011118.png

  1. let addMap = function (map, c) {
  2. if (!map.has(c)) {
  3. map.set(c, 1);
  4. } else {
  5. map.set(c, map.get(c) + 1);
  6. }
  7. }
  8. /**
  9. * @param {string} s 待匹配串
  10. * @param {string} t 子串
  11. * @return {string} 返回的字符串
  12. */
  13. var minWindow = function (s, t) {
  14. let need = new Map();
  15. let window = new Map();
  16. let left = 0, right = 0;
  17. let valid = 0;
  18. let start = 0, len = Infinity;
  19. for (let c of t) {
  20. addMap(need, c);
  21. }
  22. while (right < s.length) {
  23. let c = s[right];
  24. right++;
  25. if (need.has(c)) {
  26. addMap(window, c);
  27. if (window.get(c) === need.get(c)) {
  28. valid++;
  29. }
  30. }
  31. while (valid === need.size) {
  32. if (right - left < len) {
  33. start = left;
  34. len = right - left;
  35. }
  36. let d = s[left];
  37. left++;
  38. if (need.has(d)) {
  39. if (window.get(d) === need.get(d)) {
  40. valid--;
  41. }
  42. window.set(d, window.get(d) - 1);
  43. }
  44. }
  45. }
  46. return len === Infinity ? "" : s.substr(start, len);
  47. };

18.最短超串

标准的滑动窗口模型

image.png

  1. /**
  2. * @param {number[]} big
  3. * @param {number[]} small
  4. * @return {number[]}
  5. */
  6. var shortestSeq = function (big, small) {
  7. const n = big.length;
  8. let res = [];
  9. let map = new Map();
  10. let minLen = n;
  11. // diff:记录滑动窗口一共需要覆盖的数字个数
  12. let diff = 0;
  13. // 数据预处理:统计需要覆盖的字符数量,放入到map中
  14. for (let e of small) {
  15. diff++;
  16. map.set(e, (map.get(e) || 0) + 1);
  17. }
  18. // 左指针和右指针初始化为0
  19. let left = 0, right = 0;
  20. while (right < n) {
  21. // 获取当前右坐标的数字
  22. const rightNum = big[right];
  23. if (map.has(rightNum)) {
  24. if (map.get(rightNum) > 0) {
  25. diff--;
  26. }
  27. map.set(rightNum, map.get(rightNum) - 1);
  28. }
  29. // 达到标准时候进行左坐标的处理
  30. while (diff === 0) {
  31. if (right - left < minLen) {
  32. minLen = right - left;
  33. res.push([left, right]);
  34. }
  35. // 获取当前左坐标的数字
  36. const leftNum = big[left];
  37. if (map.has(leftNum)) {
  38. map.set(leftNum, map.get(leftNum) + 1);
  39. if (map.get(leftNum) > 0) {
  40. diff++;
  41. }
  42. }
  43. left++;
  44. }
  45. right++;
  46. }
  47. if (res.length) {
  48. return res[res.length - 1];
  49. } else {
  50. return [];
  51. }
  52. };

567.字符串的排列

这个滑动窗口是一个变种,即窗口大小是固定的,左右同时移动

image.png

/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
var checkInclusion = function (s1, s2) {
    let l = 0, r = s1.length - 1;
    let s1Map = new Map();
    for (let c of s1) {
        s1Map.set(c, (s1Map.get(c) || 0) + 1);
    }
    while (r < s2.length) {
        let map = new Map();
        for (let i = l; i <= r; i++) {
            const ch = s2[i];
            map.set(ch, (map.get(ch) || 0) + 1);
        }
        let res = cmpHash(s1Map, map);
        if (res === true) {
            return true;
        }
        l++;
        r++;
    }
    return false;

    /**
     * 比较是否重合
     * @param {Map} map1 参照哈希表
     * @param {Map} map2 需要判断的哈希表
     */
    function cmpHash(map1, map2) {
        for (let i of map1.keys()) {
            if (!map2.has(i)) {
                return false;
            } else if (map1.get(i) > map2.get(i)) {
                return false;
            }
        }
        return true;
    }
};

209.长度最小的子数组

image.png

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function (target, nums) {
    // 前缀和,[i,j)
    let sum = [];
    sum[0] = nums[0];
    const n = nums.length + 1;
    for (let i = 1; i < n; i++) {
        sum[i] = sum[i - 1] + nums[i - 1];
    }
    console.log(sum);
    let l = 0, r = 1;
    let minLen = Infinity;
    while (r < n) {
        let delta = sum[r] - sum[l];
        if (delta < target) {
            r++;
        }
        while (delta >= target) {
            if (r - l < minLen) {
                minLen = r - l;
            }
            console.log(l + ":" + r);
            l++;
            delta = sum[r] - sum[l];
        }
    }
    if (minLen === Infinity) {
        return 0;
    } else {
        return minLen;
    }
};