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 empty string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
在实现中就是维护一个HashMap,一开始key包含字典中所有字符,value就是该字符的数量,然后遇到字典中字符时就将对应字符的数量减一。算法的时间复杂度是O(n),其中n是字符串的长度,因为每个字符再维护窗口的过程中不会被访问多于两次。空间复杂度则是O(字典的大小),也就是代码中T的长度。
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*/ 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")); } }