package com.interview.flag.f; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * Created_By: stefanie * Date: 15-1-28 * Time: 下午10:02 */ public class F12_MinimunWindowSubstringWithOrder { public String minSubstring(String str, String pattern){ if(str == null || str.length() == 0) return str; if(pattern == null || pattern.length() == 0 || pattern.length() > str.length()) return ""; String minSubstring = ""; HashMap<Character, List<Integer>> indexes = new HashMap(); for(int i = 0; i < pattern.length(); i++) indexes.put(pattern.charAt(i), new ArrayList()); int[] currentIndex = new int[pattern.length()]; int idx = 0; for(int i = 0; i < str.length(); i++){ if(idx < pattern.length() && str.charAt(i) == pattern.charAt(idx)) { //haven't found all the chars currentIndex[idx] = i; idx++; } if (indexes.containsKey(str.charAt(i))) { indexes.get(str.charAt(i)).add(i); if(idx == pattern.length() && str.charAt(i) == pattern.charAt(pattern.length() - 1)){ //found all the chars, and start to shrink //shrink from the end to begin, shrink the index to higher if its value smaller than the index of all chars in its right to keep the order. for(int j = pattern.length() - 1; j >= 0; j--){ List<Integer> pos = indexes.get(pattern.charAt(j)); for(int p = pos.size() - 1; p >= 0 && pos.get(p) > currentIndex[j]; p--){ if(j == pattern.length() - 1 || pos.get(p) < currentIndex[j+1]) { //check if the shrink index is smaller than next char to keep the order currentIndex[j] = pos.get(p); //do shrink break; } } } int end = currentIndex[pattern.length() - 1]; int begin = currentIndex[0]; if(minSubstring.length() == 0 || end - begin + 1 < minSubstring.length()) minSubstring = str.substring(begin, end + 1); } } } return minSubstring; } public static void main(String[] args){ F12_MinimunWindowSubstringWithOrder finder = new F12_MinimunWindowSubstringWithOrder(); System.out.println(finder.minSubstring("UAXXBAUB", "AB")); //AUB System.out.println(finder.minSubstring("UAXSSXSXAAUB", "XXA")); //XSXA } }