LeetCode | 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"
.
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是可能包含重复字符的,ABCC的前三个元素就能完全包含ABC的字符,故判断窗口何时已完全包含t的字符是个难点 //思路是用双指针维护一个窗口,当窗口完全包含的t的字符时,移动head直到不能再移动为止 public class Solution { public String minWindow(String s, String t) { if(s==null || s.length()==0) { return ""; } //根据字符串t建立一个字典:map< char, char在t中重复的次数 > Map<Character, Integer> map = new HashMap<Character, Integer>(); for(int i=0; i<t.length(); i++){ char myChar = t.charAt(i); if(map.containsKey(myChar)){ map.put(myChar, map.get(myChar)+1); }else{ map.put(myChar, 1); } } int head = 0; //头指针 int count = 0; //用来判断窗口是否已经完全包含t的字符 int start = 0; //最小窗口的起始位置 int minLength = Integer.MAX_VALUE; //最小窗口的长度 for(int tail=0; tail<s.length(); tail++){ //尾指针不断向后遍历 char tailChar = s.charAt(tail); if(map.containsKey(tailChar)){ //如果不包含,就直接continue map.put(tailChar, map.get(tailChar)-1); if(map.get(tailChar) >= 0){ //在串t中仅出现了一次的char,仅仅能让count加1 count++; //当count加到t.length时,窗口[head-tail]一定完整的包含t串了,只可能多,不可能少 } //若t=ABCC,当tail遍历到窗口ADOBECC的第二个C,此时count=4,但第二个C是多余的 while(count == t.length()){ //此时窗口[head-tail]已经完整包含t了,向右移动head,直到 if(tail-head+1 < minLength){ //窗口不在包含t了 minLength = tail-head+1; //当前的窗口比以前选定的窗口更小,就更新最小窗口 start = head; } char headChar = s.charAt(head); if(map.containsKey(headChar)){ //窗口head处的字符位于串t之中 map.put(headChar, map.get(headChar)+1); if(map.get(headChar) > 0){ //说明在上面加一操作之前,map.get(headChar)=0 count--; //说明headChar是必须的,不能少了的 } } head++; } } } if(minLength > s.length()){ return ""; } return s.substring(start, start+minLength); } }