题目描述
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
滑动窗口。设置left,right两个游标。滑动right,直到left与right中包含了字符串T中的全部元素后,滑动left;当left与right中不包含字符串T中的全部元素时,停止滑动left,接着滑动right。重复上述步骤直至right到达字符串S的末尾。
代码(c++)
class Solution {
public:
string minWindow(string s, string t) {
string res;
map<char,int> mpt;
map<char,int> mps;
for(int i=0;i<t.length();i++){
if(mpt.find(t[i])==mpt.end()) mpt[t[i]]=1;
else mpt[t[i]]+=1;
}
int left=0,right=0;
int count=0;
int m_left=0,m_right=s.length();
while(right<s.length()){
if(mpt.find(s[right])!=mpt.end()){
if(mps.find(s[right])==mps.end()) mps[s[right]]=1;
else mps[s[right]]+=1;
if(mpt[s[right]]==mps[s[right]]) count+=1;
}
while(count==mpt.size()){
if((right-left)<(m_right-m_left)){
m_left=left;
m_right=right;
}
if(mps.find(s[left])!=mps.end()){
mps[s[left]]-=1;
if(mps[s[left]]<mpt[s[left]]) count-=1;
if(mps[s[left]]==0){
mps.erase(mps.find(s[left]));
}
}
left+=1;
}
right+=1;
}
if(m_right==s.length()) return res;
for(int i=m_left;i<=m_right;i++) res+=s[i];
return res;
}
};