题目描述
![](https://i-blog.csdnimg.cn/blog_migrate/dcad395ae235fea0073a3bf1c21cd9e0.png)
思路:滑动窗口+哈希表
采用一个哈希表,哈希表键为T中的每个字符,值为T中每个字符出现次数的相反数。
用快慢双指针遍历S,双指针之间的内容即为滑动窗口。滑动窗口中某个字符如若是哈希表中的键,则对应值加1。如果哈希表中的每一个值都非负,说明该滑动窗口覆盖T。对于每一个快指针,尝试右移慢指针缩短窗口,并维护最短覆盖字串的起止位置。
设ns表示S的长度,nt表示T的长度,C表示字符集合大小,空间复杂度为O(C),时间复杂度为O(C*ns+nt)。(最多有O(ns)个滑动窗口,每次check需要O(C)时间)
核心代码
bool check(unordered_map<char,int>& hash){
for(auto x:hash){
if(x.second<0) return false;
}
return true;
}
string minWindow(string S, string T) {
unordered_map<char,int> hash;
for(auto x:T){
--hash[x];
}
int fast=-1,slow=0;
int start,end;
int ns=S.length();
int cnt=ns+1;
while(++fast<ns){
if(hash.count(S[fast])) ++hash[S[fast]];
while(check(hash)){
if(fast-slow+1<cnt){
cnt=fast-slow+1;
start=slow;
end=fast;
}
if(hash.count(S[slow])) --hash[S[slow]];
++slow;
}
}
if(cnt==ns+1) return "";
return string(S.begin()+start,S.begin()+end+1);
}