zoukankan      html  css  js  c++  java
  • [LeetCode] Minimum Window Substring

    Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

    For example, S = "ADOBECODEBANC" T = "ABC"

    Minimum window is "BANC".

    Note: If there is no such window in S that covers all characters in T, return the emtpy string "".

    If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

    看看From LeetCode Discuss:

    O(n) Solution

    The method I used was to map the characters and how many are in the substring vs how many are needed.  If all the values are non-negative, then you can remove characters from the start of the substring until you reach a negative, and if there's a negative, you add to the end of the substring until it is 0 again.  You continue this until you've reached the end of S, and then remove characters until you have a negative count for one of the characters.

    Going through the example, S="ADOBECODEBANC" and T="ABC".  Starting out, the map has the values A=-1, B=-1, C=-1, and has a count of 3 negatives.  Adding the first letter increases A to 0, which removes a negative, leaving a count of 2.  You can count the others as well, since they will never become negative, resulting in A=0,B=0,C=0,D=1,O=1,E=1 when you add the C.  Since the negative count is 0, you start removing characters from the start, which is A, dropping it to -1, and switching back to adding at the end.

    You then add to the end until you reach an A again, which results in A=0,B=1,C=0,D=2,E=2,O=2 and a count of 0.  Remove from the start until you reach a negative again, which removes D,O,B,E,C, since B's removal only drops it to 0, not a negative.  At that point, the substring is "ODEBA" and C = -1.  Add to the end until you reach a C and you have "ODEBANC", and remove from the start until you get a negative again, leaving "ANC". You've reached the end of the string and have a negative, so there is no shorter string remaining with all the characters.

    You can retrieve the shortest substring by taking the start and end indices of the mapped substring whenever you switch from removing to adding and storing them if they are shorter than the previous shortest.  If you never switch from removing to adding, then the result is the empty string.

    If S="BANC" and T="ABC", then the result is adding until you reach "BANC", switching to remove, hitting a negative (and therefore copying those lengths at 0 and 3), and attempting to add beyond the end which ends the algorithm with the substring starting at 0 and ending at 3.

    As every character gets adding once and removed once or less, it takes 2n steps at most to complete the algorithm, an O(n) solution.

    class Solution {
      private:
          int count1[256];
          int count2[256];
      public:
          string minWindow(string S, string T) {
              // Start typing your C/C++ solution below
              // DO NOT write int main() function
              if (T.size() == 0 || S.size() == 0)
                return "";
                 
             memset(count1, 0, sizeof(count1));
             memset(count2, 0, sizeof(count2));
            
             for(int i = 0; i < T.size(); i++)
             {
                 count1[T[i]]++;
                 count2[T[i]]++;
             }
             
            int count = T.size();
             
             int start = 0;
             int minSize = INT_MAX;
             int minStart;
            for(int end = 0; end < S.size(); end++)
             {
                 if (count2[S[end]] > 0)
                {
                     count1[S[end]]--;
                     if (count1[S[end]] >= 0)
                         count--;
                 }
                 
                 if (count == 0)
                 {
                     while(true)
                     {
                         if (count2[S[start]] > 0)
                         {
                             if (count1[S[start]] < 0)
                                 count1[S[start]]++;
                             else
                                 break;
                         }
                         start++;
                     }
                 
                     if (minSize > end - start + 1)
                    {
                         minSize = end - start + 1;
                        minStart = start;
                    }
                }
             }
             
            if (minSize == INT_MAX)
                 return "";
            
            string ret(S, minStart, minSize);
            
             return ret;        
         }
     };
  • 相关阅读:
    14.1.1 使用InnoDB 表的好处:
    7.5.1 Point-in-Time Recovery Using Event Times 使用Event Times 基于时间点恢复
    7.5 Point-in-Time (Incremental) Recovery Using the Binary Log 使用binay log 基于时间点恢复
    7.4.1 Dumping Data in SQL Format with mysqldump
    7.3.2 Using Backups for Recovery 使用备份用于恢复
    7.3.1 Establishing a Backup Policy
    RR 和RC隔离问题
    mark
    weblogic12
    转一篇对EJB理解的文章
  • 原文地址:https://www.cnblogs.com/Xylophone/p/3916962.html
Copyright © 2011-2022 走看看