思路
双指针维护一个滑动窗口
移动右指针,包含t的子串时停止
移动左指针,尽量减小滑动窗口长度,当滑动窗口内的字符串不包含t时,左指针停止移动, 右指针移动,直到满足包含t停止,在重复移动左指针。
代码
/**
* @param {string} s
* @param {string} t
* @return {string}
*/
var minWindow = function (s, t) {
//左右指针
let l = 0;
let r = 0;
//包含t的字典
const need = new Map()
for (let i of t){
//滑动窗口所需的字符和对应字符的个数
need.set(i,need.has(i) ? need.get(i) + 1 : 1);
}
let res = ''
let needType = need.size;
//移动右指针
while (r < s.length) {
const a = s[r];
//右指针移动期间对应的字符在字典里的话,字典里对应字符的就-1
if(need.has(a)){
need.set(a,need.get(a) - 1);
if(need.get(a) === 0) needType--
}
/**
结束条件:字典里对应的value和为0
循环一遍太麻烦了,设一个变量needType来当need的长度
如果1个value为0就--
*/
// 此时滑动窗口包含t现在该减小长度了,移动左指针
while(needType === 0){
const newRes = s.substring(l,r+1)
if(!res || newRes.length < res.length) res = newRes
const a = s[l]
if(need.has(a)){
//左指针移动期间对应的字符在字典里的话,字典里对应字符的就+1
need.set(a,need.get(a) + 1);
if(need.get(a) >= 1) needType++
}
l++;
}
r++;
}
return res;
};
复杂度
时间:O(t.length + s.length) = O(n)
空间:O(t.length)