给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
解题思路:滑动窗口;
1,窗口是[start,end],end不断向右扩展,知道包含了所有T中的字符为止,此时start不断向左扩展,直到不能缩小位置(这是滑动窗口的大体思路)
2,判断不能缩小的依据是定义两个map,一个need,一个window,need是记录T中字符出现的次数,window是当前窗口中包含的且是T中的字符出现的次数,当window中的各值的value值大于等于need对应的value值时,满足条件。
(画外音:终于过了这道题了,还是太菜了,好多细节都没有注意到)
细节:1,js中的map函数是不能直接map.get(key)++,这是不允许的。
2,注意flag初始值的设定。
3,认真点
var minWindow = function(s, t) {
var ans='',start=0,end=0,match=0,len=s.length-1,minlen=s.length+1,flag;
var need = new Map();
var win = new Map();
for(var i = 0;i<t.length;i++){
var num = need.get(t[i]);
if(!isNaN(num)){
num++;
need.set(t[i],num);
}else{
need.set(t[i],1);
}
if(!win.get(t[i])){
win.set(t[i],0);
}
}
while(end<=len){
var num_end = win.get(s[end]);
if(!isNaN(num_end)){
num_end++;
win.set(s[end],num_end);
if(num_end == need.get(s[end])){
match++;
}
}
end++;
while(match == need.size){
if(end-start<minlen){
minlen=end-start;
flag = start;
}
var num_start =win.get(s[start]);
if(num_start > 0){
num_start--;
win.set(s[start],num_start);
if(num_start < need.get(s[start])){
match--;
}
}
start++;
}
}
if(!isNaN(flag)){
ans = s.substr(flag,minlen);
}
return ans;
};