这道题也是字符串和sliding window的题目,多了hash的步骤。。
以这个为模板可以连续AC掉,LeetCode438,LeetCode567。
struct res
{
int begin=0,end=0,chang=INT_MAX;
};
class Solution {
public:
string minWindow(string s, string t) {
if(t == "") return "";
int low=0,high=0;
unordered_map<char,int> us;//映射t的字符串中的每个字符->数量
for(auto c:t)
{
us[c]++;
}
unordered_map<char,int> uss;//映射s字符串中的每个字符串->数量
res r;//因为要找包含t字符串的最短的s的子串,所以要存一下子串的起点和终点还有长度,最后输出是截取原字符串就行
int tui=0;//在循环到s的末尾时,high会加到==s.size(),所以这时要有一个判断,防止数组越界;同时在判断长度之后,退出整个循环
while(high<=s.size())
{
int flag=0;
for(auto c:us)//检查现在的子串是否包含了,t字符串中的所有字符
//如果没包含任何一个,high++,跳出for,接着判断,再检查
//如果全部包含,flag仍然为0,进入下面if判断
{
if(uss[c.first]<us[c.first])
{
if(high == s.size())
tui=1;
uss[s[high]]++;
high++;
flag=1;
break;
}
}
if(flag == 0)//如果全部包含,判断现在子串长度和已存在的长度的大小,同时记录起点和终点和长度,同时low++更新窗口的大小和窗口内字符数量
{
if(r.chang>high-low)//长度比之前小的话,更新起点和终点和长度
{
r.begin=low;
r.end=high;
r.chang=high-low;
}
if(tui == 1)//当high==s.size()时,在上面判断长度之后才退出
break;
uss[s[low]]--;//更新窗口的大小和窗口内字符数量
low++;//更新窗口的大小
}
}
return r.chang==INT_MAX?"":s.substr(r.begin,r.end-r.begin);//如果存在子串则返回,那个最短子串,否则返回空串
}
};