雙指標比for迴圈快-LeetCode76-最小覆蓋子串
阿新 • • 發佈:2018-12-04
題目
給定一個字串 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; } }
總結
雙指標更快。