Wednesday, October 30, 2013

Minimum Window Substring [Leetcode]

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.

Solution: Two pointers [start, end] are needed to maintain the valid window (i.e., the window that covers all characters in T). One hash table needFound is used to track the number of each char in T we need to find; another hash table hasFound is used to track the number of each char in T we have already found. If hasFound[T[i]] \ge needFound[T[i]] for each char i in T, we know we have already found a valid window. We scan the string of S forward one char by one char and shrink the window if necessary.  Here is the detailed explanation of the solution.

class Solution {
public:
    string minWindow(string S, string T) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        string ret;
        if(S.empty()||T.empty()||S.size()<T.size()) 
            return ret;

        //Initilize needFound and hasFound
        unordered_map<char, int> needFound, hasFound;
        for(int i=0; i<T.size(); ++i){
            if(needFound.find(T[i])==needFound.end()){
                needFound[T[i]]=1; hasFound[T[i]]=0;
            }
            else
                needFound[T[i]]++;
        }
        int minLength = INT_MAX, minBegin = 0;
        int count = 0;
        for(int start=0, end=0; end<S.size(); ++end){
            if(needFound.find(S[end])==needFound.end())
                continue;
            hasFound[S[end]]++;
            if(hasFound[S[end]]<=needFound[S[end]])
                count++;
            if(count==T.size()){
                while(needFound.find(S[start])==needFound.end() || hasFound[S[start]]>needFound[S[start]]){
                    if (needFound.find(S[start])!=needFound.end() && hasFound[S[start]]>needFound[S[start]])
                        hasFound[S[start]]--;
                    start++;
                }
                if(end-start+1<minLength){
                    minBegin = start;
                    minLength = end-start+1;
                }
            }
        }
        if(count==T.size())
            ret = S.substr(minBegin, minLength);
        return ret;
    }
}; 

No comments:

Post a Comment