找到字符串S中的最小窗口,它将包含字符串T的所有字符

时间:2012-06-02 21:33:36

标签: c string algorithm

  

给定字符串S和字符串T,找到S中的最小窗口,其中包含复杂度为O(n)的T中的所有字符。

例如,

S = "ADOBECODEBANC"
T = "ABC"

最小窗口为"BANC"

void getstring(char str1[],char str2[],char hash[])
{

    int len=strlen(str1);
    int i=0,j;              //i keeps the previous index
    int min=INT_MAX;
    int cnt=0;  
    for(j=0;j<len;j++)
        {
            if(hash[str1[j]]==-1)   //means uninitialized, will be checked for first time only
            {

                cnt++;              
                hash[str1[j]]=j;                    

                if(cnt==1)
                i=j;

                int y=check(hash,str2); //checking for the characters
                //printf("y=%d",y);
                if(y)       //means all the characters are present
                {
                    if( (j-i+1)<min)
                    {
                    min=j-i+1;
                    I=i;
                    J=j;
                    }               


                }


               }
                else if(hash[str1[j]]>=0)
                {


                    hash[str1[j]]=j;



                    if(check(hash,str2) )
                    {                   

                    if( hash[str1[i]]==hash[str1[j]] )      //it means that we are moving the first
                    {                       //index only
                    i=getmin(hash,str2);    //get minimum index of the element              

                        if( (j-i+1)<min)
                        {
                            min=j-i+1;
                            I=i;
                            J=j;
                        }


                    }
                    //else
                    }
                    else
                    {
                    if( hash[str1[i]]==hash[str1[j]] )
                    i=hash[str1[i]];                        
                    }

                }//end of else-if
                }//end of for    
}

我已经使用hash为它创建了代码,即我保持字符串T的字符的索引值在哈希中并使用两个索引,只要我得到任何前面的字符与下面索引处的字符相同,我首先检查长度,然后更新索引。

在最坏的情况下,这种方法需要O(nk)。

n - is the number of characters in S
k - is the number of characters in T

是否有任何方法需要O(n)时间来解决此问题?

2 个答案:

答案 0 :(得分:3)

所以,在你最后一次看到T中的每个字母的时候,记录一下S的传递。

在每个点上,最后看到的字母中最远的字母将分隔窗口的左边缘(当前点是右边缘)。

在这些窗口中,只需跟踪到目前为止看到的最小窗口。在算法结束时,这将是整个最小的窗口。

答案 1 :(得分:0)

这是我的java代码已通过所有测试用例。我希望它也可以帮到你。

public class Solution {
    public String minWindow(String s, String t) {

         if(t.length()>s.length()) 
        return "";
    String result = "";

     HashMap <Character, Integer> shouldFind = new HashMap<Character, Integer>();
     HashMap <Character, Integer> hasFound = new HashMap<Character, Integer>();
     int count =0, j=0,  minWindow = s.length()+1, start=0, finish =0;

     Integer sLength = s.length();
     Integer tLength = t.length();

     for(int i = 0 ; i < tLength ; i++)
     {
         char tChar = t.charAt(i);
         if(!shouldFind.containsKey(tChar))
         shouldFind.put(tChar,1);
         else 
         shouldFind.put (tChar ,shouldFind.get(tChar)+1);

     }


     for (int i =0; i <sLength; i ++)
     {
         char sChar = s.charAt(i);

         if(shouldFind.containsKey(sChar))
         {
             if(!hasFound.containsKey(sChar)){
             hasFound.put(sChar, 1);
             count++;
             }
             else {
                 if(hasFound.get(sChar) < shouldFind.get(sChar) )
                 count ++;

             hasFound.put(sChar, hasFound.get(sChar) +1);

             }
         }




        if(count == tLength)
        {
            char ch = s.charAt(j);

          while (!hasFound.containsKey(ch) || hasFound.get(ch) > shouldFind.get(ch))
          {
              if(hasFound.containsKey(ch) && hasFound.get(ch)>shouldFind.get(ch))
              hasFound.put(ch , hasFound.get(ch) -1);

              j++;
              ch = s.charAt(j);
          }

            //lets find the minimum window
            if(minWindow > (i-j+1) )
            {
                minWindow = i - j + 1;
                start = j;
                finish = i+1;
                result = s.substring(start, finish);

            }

        }}




        return result;
    }}