采用滑动窗口,如下图所示,
- i的增加是为了让子串满足,包含目标子串,
- j的增加是为了优化最短子串,所以增加,直到不满条件时候,才会去增加i
- 借用了charCode码
- A-Za-z 相对于A的位置距离都是唯一的,一直目标字符串ABC,让他们对应出现在Arr中的值都为1,而用i遍历字符串s的是为了消除Arr中的1,没遍历到一个字符,直接让在Arr中的值减一即可。
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"));