76. 最小覆盖子串
class Solution {
public:
string minWindow(string s, string t) {
vector<int> chars(128,0);
vector<bool> flag(128,false);
//循环获取t中字符
for(int i = 0; i < t.size(); i++)
{
flag[t[i]] = true;
chars[t[i]]++;
}
int cnt = 0;//用于记录s中已有t中字符的数量
int l = 0;//记录滑动窗的左侧端点
int min_l = 0;
int min_size = s.size() + 1;
for(int r = 0; r < s.size(); r++)
{
//如果s当前遍历的字符是t中的字符
if(flag[s[r]])
{
//如果当前字符的数量还没有达到t中字符的数量,就将计数位+1
if(--chars[s[r]] >= 0)
{
cnt++;
}
//如果当前找到的t中字符的数量已经达到t的大小,即当前的字符串片段已经满足要求,那下面要做的就是尽可能的缩短字符串片段的长度
while(cnt == t.size())
{
//r是当前滑动窗口的右端点,l是左端点
//如果当前滑动窗口的长度小于min_size就更新滑动窗口的左右端点
if(r-l+1 < min_size)
{
min_l = l;
min_size = r - l + 1;
}
//这里需要特别注意的是char中最初记录的是t中各个字符的数量,但是在遍历s的过程中,s中不仅仅只包含一个t中字符,所以会被减为负值,这里判断++char[s[l]]>0就是为了在当前滑动窗口中保留至少一个t中的字符
if(flag[s[l]] && ++chars[s[l]] > 0)
{
cnt--;
}
l++;
}
}
}
return min_size > s.size() ? "" : s.substr(min_l,min_size);
}
};