剑指 Offer II 017. 含有所有字符的最短字符串

183 阅读1分钟

剑指 Offer II 017. 含有所有字符的最短字符串

采用滑动窗口,如下图所示,

  • i的增加是为了让子串满足,包含目标子串,
  • j的增加是为了优化最短子串,所以增加,直到不满条件时候,才会去增加i
  • 借用了charCode码
  • A-Za-z 相对于A的位置距离都是唯一的,一直目标字符串ABC,让他们对应出现在Arr中的值都为1,而用i遍历字符串s的是为了消除Arr中的1,没遍历到一个字符,直接让在Arr中的值减一即可。

image.png

var minWindow = function (s, t) {
  var len1 = s.length;
  var len2 = t.length;
  if (len1 < len2) {
    return "";
  }
  var res = "";
  // 优化下标
  var j = 0;
  var arr = new Array(60).fill(0);
  for (var i = 0; i < len2; i++) {
    ++arr[t[i].charCodeAt() - "A".charCodeAt()];
    --arr[s[i].charCodeAt() - "A".charCodeAt()];
  }
  if (noPositive(arr)) {
    return s.slice(0, len2);
  }
  for (var i = len2; i < len1; i++) {
    --arr[s[i].charCodeAt() - "A".charCodeAt()];
    while (noPositive(arr)) {
      if(res.length === 0 || res.length >= s.slice(j, i + 1).length){
        res = s.slice(j, i + 1);
      }
      if (res.length === len2) {
        return res;
      }
      ++arr[s[j].charCodeAt() - "A".charCodeAt()];
      j++;
    }
  }
  return res
};
// true代表 是子串
function noPositive(arr) {
  var flag = arr.every((item) => item <= 0)
  return flag;
}

调试代码

console.log(minWindow("ABAACBAB", "ABC"));
console.log(minWindow("ADOBECODEBANC", "ABC"));