1.问题描述:s的子串覆盖t的所有元素,不要求顺序。只看s子串中玩不完全包含t的所有元素。
     a,双指针同时指向s的头,后指针先往后移,前指针不动,一直移到了刚好包含t。(这是一个子串,记录大小找下一个)
     b,此时移动前指针移到刚好不包含t,继续移动后指针,再到刚好包含t,此时这个窗口大小是上面这个尾部时的最小窗口。
     c,重复ab过程直至最后一次移动后指针时大于s的长度。
3.简述为什么这样可以找到,这是遍历法的改进,遍历法就是找出所有长度大于s的子集,看看谁最小,滑动窗口简化了,
   因为a过程刚好包含了t之后,后面再有也不会比这个集合小了。b过程就是找以刚刚这个刚好包含的这个可行解的最优解。eg:t:xy s:zzxy y或zxy y

4.怎么知道刚好包含,哈希表,键是t的每个元素,键值是键的频数
   初始化键值都是-1(重复2的就是-2),在后指针移动的过程中,遇到对应的键,键值就+1,
classSolution {
public:
    //检查是否有小于0的
    bool check(unordered_map<char, int> &hash) {
        for(auto iter = hash.begin(); iter != hash.end(); iter++) {
            if(iter->second < 0)
                returnfalse;
        }
        returntrue;
    }
    string minWindow(string S, string T) {
        int cnt = S.length() + 1;
        //记录目标字符串T的字符个数
        unordered_map<char, int> hash;
        for(int i = 0; i < T.length(); i++)
            //初始化哈希表都为负数,找的时候再加为正
            hash[T[i]] -= 1;     //是频数-=
        int slow = 0, fast = 0; 
        //记录找到的局部最优解左右区间
        int left = -1, right = -1; 
        for(; fast < S.length(); fast++){
            char c = S[fast];
            //目标字符匹配+1
            if(hash.count(c))   
            hash[c]++;
            //没有小于0的说明都覆盖了,缩小窗口,即可以移动前指针了
            while(check(hash)){  
                //取最优解 
                if(cnt > fast - slow + 1){
                    cnt = fast - slow + 1;    //cnt记录以当前后指针所在位置为结尾的最优解的长度
                    left = slow;
                    right = fast;
                }
                char c = S[slow];
                if(hash.count(c))  //如果前指针指向的元素在hash中,即是t的元素,
                   {                             //   需要进去把他的次数-1,(因为要滑动窗口划过去了)
                    //缩小窗口的时候减1
                    hash[c]--;
                    }
                //窗口缩小
                slow++;     
          }
      }
      //找不到的情况
      if(left == -1)    
          return"";
      returnstring(S.begin() + left, S.begin() + (right + 1));
  }
};