题目描述:
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
思路:
滑动窗口思想
1、用哈希表need记录必须包含的字符,用一个变量cnt记录需要包含的字符串的长度
2、left表示滑动窗口的左边界,
right表示滑动窗口的右边界,
start表示满足条件的滑动窗口的起始位置,
res表示最短的滑动窗口的长度
3、遍历给定的字符串,如果是必须包含的字符,那么cnt–,直到找到包含所有字符的滑动窗口,缩短该滑动窗口,更新最短长度和起始位置
4、左边界右移,重复前面的步骤,找到最短的长度
原文戳这里
代码如下:
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char,int>need;
for(auto c:t){//记录必须包含的字符
need[c]++;
}
int res=INT_MAX,l=0,r=0,start=0,cnt=t.size();
while(r<s.size()){//滑动窗口最右边的边界
if(need[s[r]]>0){//包含必须的字符后,长度减一
cnt--;
}
need[s[r]]--;
if(cnt==0){
while(l<r&&need[s[l]]<0){//缩减窗口
need[s[l]]++;
l++;
}
if(r-l+1<res){//更新窗口
res=r-l+1;
start=l;
}
need[s[l]]++;//左边界右移寻找下一个满足条件的窗口
l++;
cnt++;
}
r++;
}
return res==INT_MAX?"":s.substr(start,res);
}
};