首先使用暴力破解求解:

使用滑动窗口的解法:

class Solution {
public:
    string minWindow(string s, string t) {
    int ssize = s.size(),tsize = t.size();
    if(ssize < tsize) return "";
    
    unordered_map<char, int> need, window;
    //初始化需要包含的字符map
    for (auto c : t) need[c]++;
    
    int left = 0, right = 0;
    int match_cnt = 0;
    // 记录最小覆盖子串的起始索引及长度
    int start = 0, len = INT_MAX;
    while (right < ssize) {
        char c = s[right];
        //右移右边界
        right++;
        
        //判断是否为需要的字符
        if(need.count(c))
        {
            window[c] += 1;
            if(window[c] == need[c])
                match_cnt += 1;
        }
        
        //当包含t中全部字符后,判断左侧边界是否可以优化
        while(match_cnt == need.size())
        {
            //rigth这里实际上指向了窗口之外
            if(right - left < len)
            {
                start = left;
                len = right -left;
            }
            
            char c = s[left];
            //左侧边界右移
            left++;
            
            //判断窗口右移后是否仍满足条件
            if(need.count(c))
            {
                if(window[c] == need[c])
                    match_cnt -= 1;
                
                window[c] -= 1;
            }
        }
        
    }
    // 返回最小覆盖子串
    return len == INT_MAX ? "" : s.substr(start, len);
}
};

运行效率:

Runtime: 20 ms, faster than 60.59% of C++ online submissions for Minimum Window Substring.
Memory Usage: 7.8 MB, less than 80.07% of C++ online submissions for Minimum Window Substring.