双指针比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;
    }
}

总结

双指针更快。

猜你喜欢

转载自blog.csdn.net/qq_36025975/article/details/83410209