import java.util.HashMap;

/**
 * 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".
 * Tags: Hash Table Two Pointers String
 * Similar Problems:  (H) Substring with Concatenation of All Words (M) Minimum Size Subarray Sum (H) Sliding Window Maximum
 * 
 * Analysis:
 * 1.Store the char in string t as a key and times appearing as value into a hashmap;
 * 2.If char at s is contained in hashmap, value(times) in map - 1 and count ++;
 * 3.When count = t.length(), minLenght and minStart records the min number
 * 4.Slide window and let the left point to the first char in s ,which is in map  
 *        s                        t        
 * A D O B E C O D E B A N C      A B C
 * A D O B E C 
 * B E C O D E B A
 * C O D E B A
 * B A N C
 * 
 * @author chenshuna
 */

public class MinimumWindowSubstring {
    public static String minWindow(String s, String t) {
        if(s.length() == 0 || t.length() ==0 || s.length() < t.length()) {
            return "";
        }
        HashMap<Character, Integer> map = new HashMap<Character, Integer>();
        for(char c : t.toCharArray()) {
            if(map.containsKey(c)) {
                map.put(c, map.get(c) + 1);
            }
            else {
                map.put(c, 1);
            }
        }
        int left = 0;
        int count = 0;
        int minStart = 0;
        int minLength = s.length() + 1;
        for(int right = 0; right < s.length(); right++) {
            if(map.containsKey(s.charAt(right))) {
                map.put(s.charAt(right), map.get(s.charAt(right)) - 1);
                if(map.get(s.charAt(right)) >= 0) { 
                    count++;
                }
                while(count == t.length()) {
                    if((right - left + 1) < minLength) {
                        minStart = left;
                        minLength = right - left + 1;
                    }
                    if(map.containsKey(s.charAt(left))) {
                        map.put(s.charAt(left), map.get(s.charAt(left)) + 1 );
                        if(map.get(s.charAt(left)) > 0) {
                            count--;
                        }
                    }
                    left ++;
                }
            }
        }
        if(minLength == s.length()+1) {
            return "";
        }
        return s.substring(minStart, minStart + minLength);
    }

    public static void main(String[] args) {
        System.out.print(minWindow("ADOBECODEBANC", "ABC"));
    }
}
@@ -1269,34 +1269,43 @@
 ) %7B%0A            
-if
+map.put(c, 
 (map.containsKey
@@ -1311,133 +1311,32 @@
 y(c)
-) %7B%0A                map.put(c, map.get(c) + 1);%0A            %7D%0A            else %7B%0A                map.put(c, 1);%0A            %7D
+ ? map.get(c) : 0) + 1);
 %0A   
@@ -2257,17 +2257,16 @@
     left
- 
 ++;%0A    

add 76