package leetcode.slidingWindow; import java.util.HashMap; /** * Solution: Sliding Window. Create a dict, and maintain a window include all T chars. * 跟longest substring 题目区别是,这里不在字典里得char,也可能是答案的一部分,所以策略是 * 1.碰到dict没有的,相当于continue,窗口继续右移, 遇到dict中的,hashMap value-1 * 2.全部包含以后,移动窗口leftBound, * 如果是不在dict中的无用字符,leftBound+1 * 如果是dict中的重复的无用字符,比如 AADOBEC. 因为window rightBound 右移过程中 -1,现在 +1 补回来,如果这样 value <= 0. 不进入step3. * 如果是dict中的字符,比如 ADOBEC, +1后应该value>0. 此时,[leftBound, i] 构成一组解,计算一下minLength. * 3. 够成一组解后,leftBound++, 此时没有全部包含,又回到step 1. 直到end. * * 什么时候全部包含了呢? * hashMap的所有key对应value全部 <= 0 的时候,这个处理太麻烦,我们用一个count来标记T length(). 每次碰见dict时候+1. * * Referenece: http://codeganker.blogspot.com/2014/03/minimum-window-substring-leetcode.html * 他的Blog非常棒,赞一个! * @author jeffwan * @date Apr 12, 2014 */ public class MinWindow { public String minWindow(String S, String T) { if (S == null || T == null || S.length() == 0 || T.length() == 0) { return ""; } // Store all character in T to HashMap. there may have duplicates. HashMap<Character, Integer> map = new HashMap<Character, Integer>(); for (int i = 0; i < T.length(); i++) { if (map.containsKey(T.charAt(i))) { map.put(T.charAt(i), map.get(T.charAt(i)) + 1); } else { map.put(T.charAt(i), 1); } } int count = 0; // T char count int leftBound = 0; String result = ""; int minLength = S.length() + 1; for (int i = 0; i < S.length(); i++) { if (map.containsKey(S.charAt(i))) { map.put(S.charAt(i), map.get(S.charAt(i)) - 1); if (map.get(S.charAt(i)) >= 0) { count++; } // Window contains all chars in T. while (count == T.length()) { if (map.containsKey(S.charAt(leftBound))) { map.put(S.charAt(leftBound), map.get(S.charAt(leftBound)) + 1); // that means S.charAt(leftBound) is the most left char in T of this window. if (map.get(S.charAt(leftBound)) > 0) { if (minLength > i - leftBound + 1) { result = S.substring(leftBound, i + 1); minLength = i - leftBound + 1; } count--; } } leftBound++; } } } return result; } }