给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""

    注意:

    • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
    • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

    示例 1:

    1. 输入:s = "ADOBECODEBANC", t = "ABC"
    2. 输出:"BANC"

    示例 2:

    输入:s = "a", t = "a"
    输出:"a"
    

    示例 3:

    输入: s = "a", t = "aa"
    输出: ""
    解释: t 中两个字符 'a' 均应包含在 s 的子串中,
    因此没有符合条件的子字符串,返回空字符串。
    

    提示:

    • 1 <= s.length, t.length <= 105
    • st 由英文字母组成

    进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?

    class Solution {
    public:
        string minWindow(string s, string t) {
            vector<int> need(128,0); //ASCII码范围是0-127
            int count = t.length(); //统计还有没找到的字符串的个数
            for(char c : t)
            {
                need[c]++;
            }
            int l=0, r=0, start=0, size = INT_MAX;
            while(r<s.length())
            {
                char c = s[r];
                if(need[c]>0) count--; //先判断是否大于0
                need[c]--;  //位置不能前,先把右边的字符加入窗口 ,小于0说明不在t内,区分开
                if(count==0)    //窗口中已经包含所需的全部字符
                {
                    while(l<r && need[s[l]]<0) //缩减窗口,出这个while时l加到了存在的t上
                    {
                        need[s[l]]++;
                        l++;
                    }   //此时窗口符合要求
                    if(r-l+1 < size)    //更新答案
                    {
                        size = r-l+1;
                        start = l; //更新最后用来取子字符串的起点
                    }
                    need[s[l]]++;   //左边界右移之前需要释放need[s[l]],后面要用到
                    l++;
                    count++;
                }
                r++;
            }
            return size==INT_MAX ? "" : s.substr(start, size);
        }
    };