1. 程式人生 > >雙指標比for迴圈快-LeetCode76-最小覆蓋子串

雙指標比for迴圈快-LeetCode76-最小覆蓋子串

題目

給定一個字串 S 和一個字串 T,請在 S 中找出包含 T 所有字母的最小子串。

示例:

輸入: S = "ADOBECODEBANC", T = "ABC"
輸出: "BANC"
說明:

如果 S 中不存這樣的子串,則返回空字串 ""。
如果 S 中存在這樣的子串,我們保證它是唯一的答案。

思路1

遍歷S作為結果的首字母,確定首字母后從首字母開始往後直到找到完整包含T的區間。超時。

程式碼1

class Solution {
    public String minWindow(String s, String t) {
        String res="";
        break1:
        for(int i=0;i<=s.length()-t.length();i++){
            boolean[] used=new boolean[t.length()];
            int usedcount=0;
            for(int j=0;j<t.length();j++){
                if(s.charAt(i)==t.charAt(j)){
                    used[j]=true;
                    usedcount++;
                    break;
                }
            }
            if(usedcount==0){
                continue;
            }
            
            if(usedcount==t.length()){
                res=s.charAt(i)+"";
                return res;
            }
            
            for(int j=i+1;j<s.length();j++){
                if(res.length()!=0 && j-i+1>=res.length()){
                    continue;
                }
                
                for(int k=0;k<t.length();k++){
                    if(!used[k] && s.charAt(j)==t.charAt(k)){
                        used[k]=true;
                        usedcount++;
                        if(usedcount==t.length()){
                            if(res.length()==0){
                                res=s.substring(i,j+1);
                            }else{
                                if(j-i+1<res.length()){
                                    res=s.substring(i,j+1);
                                }else{
                                    
                                }
                            }
                            continue break1;
                        }
                        break;
                    }
                }
            }
            
            
        }
        return res;
    }
}

思路2

雙指標i,j。初始i=j=0。j++直到完整包含字串T,初始化結果。然後i++,如果更短則更新結果,直到不包含完整字串T。繼續j++直到完整包含字串T,如果更短則更新結果。然後i++,如果更短則更新結果,直到不包含完整字串T。以此類推。

程式碼2

class Solution {
    public String minWindow(String s, String t) {
        
        String res="";
        if(s.length()<t.length()){
            return res;
        }
        
        // map存字串t所有字母及其數量
        Map<Character,Integer> tt=new HashMap<Character,Integer>();
        for(int i=0;i<t.length();i++){
            if(tt.get(t.charAt(i))==null){
                tt.put(t.charAt(i),1);
            }else{
                tt.put(t.charAt(i),tt.get(t.charAt(i))+1);
            }
        }
        int tcount=t.length();
        
        int i=0;
        int j=0;
        // 1:i++; 2:j++; -1:i=j=0;
        int action=-1;
        if(tt.get(s.charAt(0))==null){
            
        }else{
            tt.put(s.charAt(0),tt.get(s.charAt(0))-1);
            tcount--;
        }
        
        while(true){
            if(j>=s.length()){
                break;
            }
            
            if(action==-1){

            }else if(action==1){
                if(tt.get(s.charAt(i-1))==null){
            
                }else{
                    tt.put(s.charAt(i-1),tt.get(s.charAt(i-1))+1);
                    if(tt.get(s.charAt(i-1))<=0){
                        
                    }else{
                        tcount++;
                    }
                    
                }                
            }else if(action==2){
                if(tt.get(s.charAt(j))==null){
   
                }else{
                    if(tt.get(s.charAt(j))<=0){
                        tt.put(s.charAt(j),tt.get(s.charAt(j))-1);
                    }else if(tt.get(s.charAt(j))>0){
                        tt.put(s.charAt(j),tt.get(s.charAt(j))-1);
                        tcount--;
                    }
                }
            }
            
            // s[i]~s[j] 是否完整包含t
            if(tcount==0){
                if(res.length()==0){
                    res=s.substring(i,j+1);
                }else{
                    if(res.length()>j-i+1){
                        res=s.substring(i,j+1);
                    }else{
                        
                    }
                }
                
                if(res.length()==t.length()){
                    return res;
                }
                // 設定下一步
                if(action==-1){
                    action=2;
                    j++;
                }else{
                    action=1;
                    i++;
                }
            }else{
                // 設定下一步
                if(action==-1){
                    action=2;
                    j++;
                }else{
                    action=2;
                    j++;
                }
            }
        }
        
        return res;
    }
}

總結

雙指標更快。