第52题 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.

Hide Tags
  Hash Table Two Pointers String













Solution in Java:
public class Solution {
    public String minWindow(String S, String T) {
        if(S==""||T==""||S.length()<T.length()) return "";
        
        //map is a hashmap for recording the times of characters in T appear,
        //and how namy times the corresponding characters appear in the window of S
        Map<Character, Integer> map = new HashMap<Character, Integer>();
       
        //build the hashmap for characters in T
        for(int m=0; m<T.length(); m++){
            char cur = T.charAt(m);
            if(map.containsKey(cur)){
                int dup = map.get(cur);
                map.put(cur, ++dup);
            }
            else
                map.put(cur, 1);
        }
        
        //need is the total number of characters in T
        int need = T.length();  
        
        //find the first window in S contains T
        int minstart=0, minend = S.length()-1;
        for(int n=0; n<S.length();n++){ 
            if(need==0){        //need =0 means the current window contains T
                minend = n-1;           
                break;
            } 
            char cur = S.charAt(n);    
            if(map.containsKey(cur)){   
                int dup = map.get(cur); 
                if(dup>0){      //dup >0 means to cover all characters in T, 
                    need--;     //still needing this character cur, so after adding cur, need-1;
                }
                map.put(cur, --dup);    
            }
        }
        if(need>0) return "";//characters in S cannot cover characters in T
        
        //shrink for the first minstart, minend
        while(!map.containsKey(S.charAt(minstart)) || map.get(S.charAt(minstart))<0){ 
            //if map contains S.charAt(minstart) and map.get(S.charAt(minstart)) < 0, that means
            //now the window in S contains more S.charAt(minstart) than it needs (the number of this                //characters appear in T), we then shrink the window
            if(map.containsKey(S.charAt(minstart))){    
                int dup = map.get(S.charAt(minstart));
                map.put(S.charAt(minstart), ++dup);
            }
            minstart++;
        }
        
        int curstart = minstart, curend = minend; 
        //on the base of curstart, curend, each time shift the window to the right by one position,
        //and check if the need is 0. If it is, we find another window that can cover T, and begin to 
        //shrink the window
        while(curend<S.length()-1){    
            char sChar = S.charAt(curstart);    
            //check if the first character that will be removed from the window is needed to cover T 
            if(map.containsKey(sChar)){     
                int dup = map.get(sChar);       
                if(dup>=0){     //only when dup>=0, this character is needed to cover T, 
                     need++;    //so after removing this character, we need one more character to                                       //cover T, need++
                }
                map.put(sChar, dup+1); //remove sChar from the window, and modify the map          
            }
            curstart = curstart + 1;            
            curend = curend + 1;                
            char eChar = S.charAt(curend); 
            
            //check if the last character that will be added to the window is needed to cover T 
            if(map.containsKey(eChar)){
                int dup = map.get(eChar);
                if(dup>0){  //only when dup>0, this character is needed to cover T
                    need--; //so after adding this character, we need one less character to cover T
                            //so we have need--
                }
                map.put(eChar, --dup);
            }
            if(need==0){    //begin to shrink
                while(!map.containsKey(S.charAt(curstart)) || map.get(S.charAt(curstart))<0){
                    if(map.containsKey(S.charAt(curstart))){
                        int dup = map.get(S.charAt(curstart));
                        map.put(S.charAt(curstart), ++dup);
                    }
                    curstart++;
                }
                minstart = curstart;                            
                minend  = curend;                               
            }
        }
        
        return S.substring(minstart, minend+1);
        
        
    }
}

Note:
1. 注意a++和++a的区别,a++第一遍先返回a再执行++(居然被这个坑了。。)
2. 首先找出S中包含T的第一个窗口(如果存在),然后以此窗口位基础,以这个宽度不断向右平移,如果新窗口能够包含T,再试图缩小窗口,获得更小的窗口
3. hashmap map中,以相应字符为key值,而相对应的value表示该字符在现在的window中是刚好(value=0), 是缺乏(value>0),还是富余(value<0)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值