输入:两个字符串 S 和 T。S = “ADOBECODEBANC”,T = “ABC”;
输出:一个 S 字符串的子串。“BANC”
在这个样例中,S 中同时包含一个 A、一个 B、一个 C 的最短子字符串是"BANC"。
function func(source, target) {
const [numOfChar, boolOfChar] = [[], []]
for (let i = 0; i < target.length; ++i) {
boolOfChar[target[i]] = true;
numOfChar[target[i]] = numOfChar[target[i]] ? ++numOfChar[target[i]] : 1;
}
let left = 0, total = 0, min_left = 0;
const len = source.length;
let min_size = len + 1;
for (let i = 0; i < len; ++i) {
// 如果当前字符正好是所需字符
if (boolOfChar[source[i]]) {
// 更新该字符当前应剩余数,同时更新子串长度
if (--numOfChar[source[i]] >= 0) {
++total;
}
// 如果子串已经包含目标字符串
while (total == target.length) {
// 如果当前子串长度小于min_size,则更新
const curSize = i - left + 1;
if (curSize < min_size) {
min_left = left;
min_size = curSize;
}
// 如果子串最左字符是所需字符,并且子串中没有出现重复字符,则尝试压缩
if (boolOfChar[source[left]] && ++numOfChar[source[left]] > 0) {
--total;
}
++left;
}
}
}
// min_size > len,说明不包含;否则进行字符串截取
return min_size > len ? "": source.slice(min_left, min_left + min_size);
}
const result = func('ADOBECODEBANC', 'ABC');
console.log(result);