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.
直接说思路吧,就是先统计T串中有多少个字符,分别出现了多少次,保存在Map map中,然后在S中找到第一个包含T中全部字符的串,设起始位置为start,结束位置为end。并记录下这个子串中T中每个字符出现的次数,保存在Map m中。
然后从start+1开始向后找到第一个在T中出现的字符,用char temp记录该字符,然后start向后找到第一个在T中出现的字符,若temp在m中出现次数大于在map中出现的次数,则比较end-start+1与min的大小并更新,否则end向后找到第一个等于temp的字符,然后更新min。
因为start和end都是从0到S.length遍历一次并且没有回溯,因此复杂度为O(n)。代码如下:
1 Map<Character, Integer> map = new HashMap<Character, Integer>(); 2 int count = 0; 3 for (int i = 0; i < T.length(); i++) { 4 if (!map.containsKey(T.charAt(i))) { 5 map.put(T.charAt(i), 1); 6 }else{ 7 map.put(T.charAt(i), map.get(T.charAt(i))+1); 8 } 9 count++; 10 } 11 int min = Integer.MAX_VALUE; 12 int pos = 0; 13 int start = -1; 14 int end = 0; 15 // find first 16 Map<Character, Integer> m = new HashMap<Character, Integer>(); 17 for(Character c:map.keySet()){ 18 m.put(c, 0); 19 } 20 for (; count > 0 && start < S.length() && end < S.length(); ++end) { 21 if (m.containsKey(S.charAt(end))) { 22 if (start == -1) { 23 start = end; 24 } 25 if (m.get(S.charAt(end)) < map.get(S.charAt(end))) { 26 count--; 27 } 28 m.put(S.charAt(end), m.get(S.charAt(end)) + 1); 29 } 30 } 31 //////////////////////////////////////////////////// 32 if (count > 0) { 33 return ""; 34 } 35 min = end - start; 36 pos = start; 37 end--; 38 for (; start < S.length() && end < S.length();) { 39 for(;start<S.length();start++){ 40 if(m.containsKey(S.charAt(start))){ 41 break; 42 } 43 } 44 if(start==S.length()){ 45 continue; 46 } 47 char temp = S.charAt(start); 48 for(++start;start<S.length();start++){ 49 if(m.containsKey(S.charAt(start))){ 50 break; 51 } 52 } 53 if(start==S.length()){ 54 continue; 55 } 56 if(m.get(temp)>map.get(temp)){ 57 if(end-start+1<min){ 58 min = end-start+1; 59 pos=start; 60 } 61 m.put(temp, m.get(temp)-1); 62 continue; 63 } 64 for(++end;end<S.length();end++){ 65 if(S.charAt(end)==temp){ 66 break; 67 } 68 if(m.containsKey(S.charAt(end))){ 69 m.put(S.charAt(end), m.get(S.charAt(end))+1); 70 } 71 } 72 if(end==S.length()){ 73 continue; 74 } 75 if(end-start+1<min){ 76 min = end-start+1; 77 pos=start; 78 } 79 } 80 return S.substring(pos, pos + min);