Thursday, January 8, 2015

LeetCode 76: 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.
public class Solution {
    public String minWindow(String S, String T) {
        // Similar to "Substring with Concatenation of All Words" but with some intervening characters
        // Used to store the characters of T and their appearing times.
        HashMap<Character, Integer> dict = new HashMap<>();
        
        for (int i = 0; i < T.length(); i++)
        {
            char c = T.charAt(i);
            
            if (!dict.containsKey(c))
                dict.put(c, 1);
            else
                dict.put(c, dict.get(c) + 1);
        }
        
        // Used to store the characters of S that also exist in T and their appearing times
        HashMap<Character, Integer> found = new HashMap<>();
        int foundCounter = 0; // Number of found qualified characters in S
        int start = 0;
        int end = 0;
        int min = Integer.MAX_VALUE;
        String minWindow = "";
        
        while (end < S.length())
        {
            char c = S.charAt(end);
            
            if (dict.containsKey(c))
            {
                if (found.containsKey(c))
                {
                    if (found.get(c) < dict.get(c))
                        foundCounter++;
                        
                    found.put(c, found.get(c) + 1);
                }
                else
                {
                    found.put(c, 1);
                    foundCounter++;
                }
            }
            
            // When foundCounter equals to T.length(), in other words, found all qualified characters.
            // Note: The sum number of 'found' is larger or equals to foundCounter
            // e.g., foundCounter = 3 ("ABC"), however, 'found' stores 2 'A', 3 'B' and 1'C'.
            if (foundCounter == T.length())
            {
                char sc = S.charAt(start);
                
                // If true, 'sc' can be removed, [start, end] still contains all of the qualified characters.
                while (!found.containsKey(sc) || found.get(sc) > dict.get(sc))
                {
                    if (found.containsKey(sc) && found.get(sc) > dict.get(sc))
                        found.put(sc, found.get(sc) - 1);
                        
                    start++;
                    sc = S.charAt(start);
                }
                
                if (end - start + 1 < min) {
                    minWindow = S.substring(start, end + 1);
                    min = end - start + 1;
                }
            }
            
            end++;
        }
        
        return minWindow;        
    }
}

No comments:

Post a Comment