1420 · 最小覆盖子串II

描述

给你一个字符串 S、一个字符串 T,S是循环的,请在字符串 S 里面找出:包含 T 所有字母的最小子串。

  • 如果 S 中不存这样的子串,则返回空字符串 ""。
  • 如果 S 中存在这样的子串,我们保证它是唯一的答案。

样例

 
示例1:
输入: 
S = "abcdc"
T = “da”
输出: "dca"
解释:你可以将S旋转成 "bcdca",因此你的最小覆盖子串就是“dca”
 
示例2:
输入:
S = "ADOBECODEBANC"
T = "DAOC"
输出: "CADO"
解释:你可以将S旋转成"BECODEBANCADO", 因此最小覆盖子串就是“CADO”

 


 string minWindowII(string &S, string &T) {
     // Write your code here
     S = S + S;
     int tSize = T.size();
     int sSize = S.size();
     vector<bool>visited(sSize+1, false);
     map<char, int> tMap;
     for (int i = 0; i < tSize; i++)
     {
         auto it = tMap.find(T[i]);
         if (it != tMap.end())
         {
             tMap[T[i]]++;
         }
         else
         {
             tMap[T[i]]=1;
         }
     }
     int start = 0;
     int end = 0;
     int minStart=0;
     int minRet=INT_MAX;
     int tmpTsize = tSize;
     map<char, int> tMapTmp=tMap;
     while (start < sSize)
     {
        


         while (tmpTsize > 0 && end < sSize)
         {
             auto it = tMapTmp.find(S[end]);
             if (it != tMapTmp.end())
             {
                 it->second--;
                 if (it->second >= 0)
                 {
                     tmpTsize--;
                 }    
             }
             end++;    
         }
        
         while (tmpTsize == 0 && start < sSize)
         {
             if (end - start < minRet)
             {
                 minRet = end - start;
                 minStart = start;
             }

             auto it = tMapTmp.find(S[start]);
             if (it != tMapTmp.end())
             {    
                 it->second++;
                 if (it->second > 0)
                 {
                     tmpTsize++;
                 }            
             }    
             start++;    
         }

         if (end == sSize)
         {
             if (start == 0)
             {
                 break;
             }
             start++;
             end = start;

             if (visited[end] == true)
             {
                 break;
             }
             visited[end] = true;
             tMapTmp = tMap;
             tmpTsize = tSize;
         }
     }
     string sRet = "";
    for (int i = minStart; minRet != INT_MAX && i < minRet + minStart; i++)
     {
         sRet += S[i];
     }

     return sRet;
 }

 void test()
 {
     //string S = "abcdc";
     //string     T = "da"; //"dca"

     //string  S = "ADOBECODEBANC";
     //string     T = "DAOC";
         输出: "CADO"


     //string  S = "JCYHY";
     //string     T = "D";
     //string ret = minWindowII(S, T);

    // string  S = "eaGxRUaIOJ";
    // string     T = "Oax";

     //string  S = "PYXLzrJYdmUHpbxmSjObMdTrIXeuKxtyneqFJkyYaCMBUiKdqZRMOHAUDGuqI";
     //string     T = "zHqXF";
     FJkyYaCMBUiKdqZRMOHAUDGuqIPYXLz
     zrJYdmUHpbxmSjObMdTrIXeuKxtyneqF
     //string ret = minWindowII(S, T); //xRUaIlcGHiO

     string  S = "DwCBNuWUcAtrcqorVwOsILwgUNLTThdBtyZmeoGehPXGUarYCVqLjxysuzUM";
     string     T = "YqTdOZjYMM";
     //YCVqLjxysuzUMDwCBNuWUcAtrcqorVwOsILwgUNLTThdBtyZmeoGehPXGUarYCVqLjxysuzUM
     string ret = minWindowII(S, T);
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值