# LeetCode算法学习之- 滑动窗口-[76. 最小覆盖子串]

65 阅读1分钟

题目

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

分析

  1. 包含所有t的最小字符串

    1. 字符串 => s.slice

    2. 最小=》 滑动窗口 + left 到达条件后 left++

解法:滑动窗口


思路
1. 因为Map会超时,所以才去字典的方式来优化时间
2. 先扩大滑动窗口直到满足条件
3. 再根据满足的情况缩进左边的的窗口 来求得最小的滑动窗口大小 
*/

// @lc code=start
/**
 * @param {string} s
 * @param {string} t
 * @return {string}
 */
var minWindow = function (s, t) {
    // 因为包含大小写英文 所以字典的最大取值范围是 'z'.charCodeAt()-'A'.charCodeAt()
  const sArr = new Array('z'.charCodeAt()-'A'.charCodeAt()+1).fill(0);
  const tArr = new Array('z'.charCodeAt()-'A'.charCodeAt()+1).fill(0);
  let minStr = "";
  let min = Infinity;
  
  const AChar = "A".charCodeAt();
  if (s.length < t.length) return minStr;

//   建立t的字典 记录t中字母出现的次数
  for (let i = 0; i < t.length; i++) {
    tArr[t[i].charCodeAt() - AChar]++;
  }
//   左边的指针
  let j = 0;
  for (let i = 0; i < s.length; i++) {
    //   满足t字典的才放入s字典中
    if (tArr[s[i].charCodeAt() - AChar]) {
      sArr[s[i].charCodeAt() - AChar]++;
    }

    // 当满足条件时候 在不断缩小左指针 来求得最小的窗口大小
    while (matchCondition() && j <= i) {
      if (i - j + 1 < min) {
        min = i - j + 1;
        minStr = s.slice(j, i + 1);
      }
      if (tArr[s[j].charCodeAt() - AChar]) {
        sArr[s[j].charCodeAt() - AChar]--;
      }
      j++;
    }
  }

//   判断是否满足条件
  function matchCondition() {
    for (let i = 0; i < sArr.length; i++) {
      if (sArr[i] < tArr[i]) return false;
    }
    return true;
  }

  return minStr;
};

//时间复杂度:O(n*m) n 为s的长度 m为t字典集的大小
//空间复杂度:O(m)

总结

今天这道题是主要是练习如何使用不固定尺寸的滑动窗口 来求连续子串类最小长度的题目

大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢

大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持

文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com

\