【问题标题】:find the minimum window in string S which will contain all the characters of string T在字符串 S 中找到包含字符串 T 的所有字符的最小窗口
【发布时间】:2012-06-02 21:33:36
【问题描述】:

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

例如,

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    
}

我已经使用哈希为其编写了代码,即我将字符串 T 的字符的索引值保留在哈希中并使用两个索引,只要我得到任何与较低索引处的字符相同的字符,我先检查长度,然后更新索引。

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

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

是否有任何方法会花费O(n) 时间来解决这个问题?

【问题讨论】:

标签: c string algorithm


【解决方案1】:

因此,通过 S 记录您最后一次看到 T 中的每个字母的时间。

在每个点,最后看到的字母中最远的一个将界定窗口的左边缘(当前点为右边缘)。

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

【讨论】:

  • 我的做法一模一样,但少了一点,我会改正的。
  • 我认为有关如何更新和跟踪这些窗口的更多详细信息会有所帮助。
  • 在每一步跟踪看到的最小窗口只是if (current &lt; min) min = current。最后看到的字符集需要按字符(数组)的完美哈希索引,也需要按最后看到的顺序通过链表索引。当最后一次看到的变化时,它需要从列表中删除并放在前面。然后列表的尾部将给出最后一次看到的最远,以及窗口的左边缘。 current_window_size = current_pos - last_seen_pos。这些都是 O(1) 操作。
  • 但是如果 S="AAAAAAA" 和 T="AA",你将如何处理这种情况。在这种情况下,我们将继续删除和插入 'A'。并且链表将是 1 个字符。因此我们不会得到“AA”。
  • 您的描述没有指定在重复字符的情况下会发生什么。在所描述的情况下,您必须跟踪最后一次看到的第 k 个字符 c,其中 k 是字符 c 在 T 中出现的次数。这只需要记录最后一个 c 的(现在是多个)条目数查看列表,并确保在第一次添加 k 之前不要删除任何列表。
【解决方案2】:

这是我通过所有测试用例的 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;
    }}

【讨论】:

    猜你喜欢
    • 2017-02-23
    • 2013-10-12
    • 2011-01-28
    • 1970-01-01
    • 2021-09-09
    • 2023-04-10
    • 2015-02-18
    • 1970-01-01
    相关资源
    最近更新 更多