1. 程式人生 > >Minimum Window Substring:最小視窗子串

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 empty string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

思路:對於字串,常規思路就是滑動視窗,這裡要求複雜度為O(n),難點在於如何判斷子串是剛好滿足要求的,這裡單獨設定一個變數count,用於統計視窗內所缺少字串的數量。先視窗右側移動,滿足要求後判斷是否最短;然後左側再移動直至不滿足要求;重複此過程,返回最小子串。

這個count最初沒想到只計數即可,還想著設一個數組反覆遍歷,但複雜度不符合要求。

class Solution {
    public String minWindow(String s, String t) {
        int m = t.length();
        int n = s.length();
        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 i = 0;
        int j = 0;
        int l = 0;
        int r = 0;
        int len = Integer.MAX_VALUE;
        int count = m;//必須的個數,包括重複
        while(l<=r&&r<n){
        	if(map.get(s.charAt(r))!=null){
        		if(map.get(s.charAt(r))>0){
        			count--;
        		}      		
        		map.put(s.charAt(r), map.get(s.charAt(r))-1); 
        	}
        	while(count == 0&&l<=r){
    			if(r-l+1<len){
    				i = l;
    				j = r;
    				len = r -l +1;
    			}
    			if(map.get(s.charAt(l))!=null){//進到這一步判斷時,已經就不用考慮重複情況了,因為去掉任意一個有用的元素就立刻不滿足情況
    				map.put(s.charAt(l), map.get(s.charAt(l))+1); 
    				if(map.get(s.charAt(l))>0){
    					count++;
    				}           		            		          	
            	}
    			l++;
    		}
        	r++;
        }
        return len==Integer.MAX_VALUE?"":s.substring(i, j+1);
    }
}