题目:
题解:
labuladong的深入浅出滑动窗口讲法,大家可以看看那个详细解法,我这里提供两份代码,一份是详细解法的代码,一份是8ms,战胜 98.87 %的代码。
代码如下:
class Solution {
public:
string minWindow_1(string s, string t) {
//最小字串的开始位置和最小长度
int start=0,minLength=INT_MAX;
unordered_map<char,int> needs;
unordered_map<char,int> window;
//建立字符串t的字符表
for(char c:t)needs[c]++;
//初始化窗口区间和记录窗口中满足的字符个数
int left=0,right=0,match=0;
//开始滑动窗口
while(right<s.size())
{
char c1=s[right];
if(needs.count(c1)){//字符c1存在于t的字符表中
window[c1]++;//加入window
if(window[c1]==needs[c1])//字符c1的个数已经满足字符表中的个数了
match++;
}
right++;
while(match==needs.size())
{
if(right-left<minLength){//窗口的大小小于最小长度,更新字符串
start=left;
minLength=right-left;
}
char c2=s[left];
if(needs.count(c2)){//c2在needs中,主要用来去除window中多余的字符数的
window[c2]--;//字符c2的个数减1
if(window[c2]<needs[c2])//字符c2出现次数不再符合要求
match--;
}
left++;//不管c2在不在needs中,都需要将left右移,因为此时的window的字符个数必然多于needs的字符个数
}
}
return minLength==INT_MAX?"":s.substr(start,minLength);
}
string minWindow_2(string s, string t){
//t不是s的字串
if(s.size()<t.size())return "";
//建立t的字符表
int count[256] = {0};
for(char c:t)count[c]++;
int left=0,right=0;//窗口的左右指针
int len=0,minLen=s.size();//len表示当前窗口匹配t中的字符个数
string result;
int n=s.size();
for(;right<n;++right){
if(count[s[right]]>0)//右指针指向s中的字符存在于count中
len++;
count[s[right]]--;//该字符的个数减1,表示s与t匹配了一个字符或者没有匹配到字符,该字符的个数可能为负数
while(len==t.size())//s中的字符串已经满足t的字符串了
{
if(right-left+1<=minLen){//窗口大小小于最小子串,更新最小子串
minLen=right-left+1;
result=s.substr(left,right-left+1);
}
count[s[left]]++;//移动窗口的左指针
if(count[s[left]]>0)len--;//字符的个数不在符合条件,表示window移动多了,正常匹配的话,count的每个字符为0
left++;
}
}
return result;
}
};