给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
解析:题目要求找出最小子串。
对于寻找子字符串的问题,可以使用滑动窗口的思想。
构建一个滑动窗口,先扩张右边界直至目前范围满足题目要求,之后尝试缩小左边界直至目前范围不满足要求,此时的滑动窗口范围子串便是目前的最优解。之后继续以上步骤
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char,int> m; //构造记录字符出现次数的hashmap
for(char c:t) ++m[c];
int count = 0; //匹配字符的数量
int min=INT_MAX; //最小子串的长度
string res; //最小子串
int l,r; //双指针,分别指向滑动窗口的两端
//右指针遍历字符串,左指针根据情况移动
for(l=0,r=0;r<s.size();++r){
--m[s[r]]; //将右指针扫描的字符记录
if(m[s[r]]>=0) ++count; //如果不存在与t的字符,此时值为-1
while(count==t.size()){ //如果目前窗口已经满足要求,尝试收缩窗口
if(r-l+1<=min){ //如果目前子串比之前小
min = r-l+1;
res = s.substr(l,r-l+1); //更新当前最小子串
}
++m[s[l]]; //删除字符记录
if(m[s[l]]>0) --count; //不存在于t中的字符,此时值最大为0
++l; //收缩滑动窗口
}
}
return res;
}
};