class Solution {
public:
/**
*
* @param S string字符串
* @param T string字符串
* @return string字符串
*/
string minWindow(string S, string T) {
// write code here
int n = S.size();
int m = T.size();
// 特判,如果S比T短,不符合题意
if( n < m)
return "";
int l = 0; // 窗口左右边界
int r = 0;
int len = INT_MAX; // 窗口长度
int start = -1; // 最小区间起始位置
// 记录T中元素出现情况,因为可能会出现一个元素出现多次的情况,故用map而不用set
unordered_map<char, int> cache;
// 记录S中出现目标元素的情况
unordered_map<char, int> window;
// 已完成覆盖的元素类别数
int valid = 0;
for(auto x : T)
cache[x]++;
//滑动
while(r < n ){
// 窗口扩展
char cur_r = S[r++];
if(cache.count(cur_r)){
window[cur_r]++;
if(window[cur_r] == cache[cur_r])
valid++;
}
//窗口收缩
while(valid == cache.size()){
if(len > r - l){
len = r - l;
start = l;
}
char cur_l = S[l++];
if(cache.count(cur_l)){
if(window[cur_l] == cache[cur_l])
valid--;
window[cur_l]--;
}
}
}
return len == INT_MAX ? "" : S.substr(start,len);
}
};