注:是2020-5-31 字节夏令营第一场笔试中的一道类似题~
代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
string minWindow(string s, string t) {
vector<int> map(128);
int left = 0, right = 0, need = t.size(), minStart = 0, minLen = INT_MAX;
for(char ch : t) ++map[ch]; //统计t中每个字符出现次数
while(right < s.size())
{
if(map[s[right]] > 0) --need; //窗口右移,每包含一个t中的字符,need-1
--map[s[right]];
++right;
while(need == 0) //完全覆盖子串时,此时字符被包含在[left,right)中
{
if(right - left < minLen) //此时字符串长度:r - l 判断是否最小
{
minStart = left;
minLen = right - left;
}
map[s[left]]++;//把s[l]弄出窗口
if(map[s[left]] > 0) ++need; //窗口左移
++left;
} //关键!map的值可以看出留在窗口里的字符 假设t中有1个A 而map[65]==0 表示有一个A在窗口里
}
//map中一旦有1个值大于0,就意味着还需要选1个才能包含全部字符
// 精髓:未全部包含 右指针向右拓展;一旦包含,左指针向左收缩,一旦未全部包含,又向右拓展
if(minLen != INT_MAX) return s.substr(minStart, minLen);
return "";
}
};