1.题目
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”
示例 2:
输入:s = “a”, t = “a”
输出:“a”
2.思路
滑动窗口,need表示还差多少个字符即可覆盖字符串t
先右移完全覆盖t子串,再左移缩小边界,然后不断进行这个过程,同时记录最小子串
3.代码
class Solution {
public:
/*
使用滑动窗口找出每个字符串t的位置:
1. 先右移right指针到包含t所有字符;
2. 然后右移left指针缩至包含t的最小窗口;
3. 记录窗口大小,继续右移right指针...
*/
string minWindow(string s, string t) {
if(s.size()<t.size())
return "";
int left = 0, right = 0, need = t.size();
int min_start = 0, min_len = INT_MAX;
unordered_map<char, int> mp;
for(char ch:t) ++mp[ch];
while(right<s.size()){
if(mp[s[right]]>0){
--need;
}
--mp[s[right]]; //s中不属于t的字符对应value永远为负值
++right;
while(need == 0){
if(right - left < min_len){ //因为前面right自增了1,所以这里不用right-left+1
min_start = left;
min_len = right - left;
}
//左移一位,恢复移走字符的计数
++mp[s[left]];
if(mp[s[left]]>0){
++need;
}
++left;
}
}
if(min_len != INT_MAX)
return s.substr(min_start, min_len);
return "";
}
};