【回溯DFS】【記憶化搜尋】97.交錯字串
阿新 • • 發佈:2022-05-10
根據題意,就是組成S3的字串,必須是由S1 S2 組成。而且順序還得是一樣的。
也就是保持S1 S2的原有順序組成S3。
然後判斷,是不是S3是不是由S1 S2組成?
那麼我們怎麼做呢?
s1:aabcc
s2: dbbca
s3:aadbbcbcac
按照上面的例子以及題意。
就是遍歷S3,拿著S3的每位字元去 S1 S2中,按著順序找
也就是說,有3個遍歷的index, i , j,k ,分別代表著遍歷s1,s2,s3
如果s1[i] == s3[k] 那麼 i ,k 均往後移動一位。
如果s2[j] == s3[k] ,j,k往後移動一位。
然後如果k遍歷到頭了,i==s1.length j=s2.length ,那麼說明s3就是由s1 s2組成。
問題來了。如果s1[i]==s2[j] ==s3[k] 呢? 我到底選擇s1 的i,k,往後移動 ,還是s2的j,k往後移動?
我不知道怎麼選擇啊,這就涉及到決策了。
涉及到決策了,那麼直接DFS,BFS,回溯,DP 中試吧。
那麼這道題,很明顯,就是如果我 選擇s1的i,k往後移動,按照他的這個分支往下走,他有可能成功,有可能不成功啊。
如果不成功,直接恢復現場就行了啊。
那麼我可以遍歷每一種選擇,那麼這是什麼啊?回溯/DFS啊。
OK,涉及到了回溯,我們必須想到 樹形結構,必須得構建出樹形結構。
那麼此題採用回溯,主要決策點在於,我選擇選擇s1 i,k 往後移動,還是 s2 j,k往後移動。
三個決策點對吧。
那麼跳出條件是什麼呢?
- 很明顯: i==s1.length&& j ==s2.length&&k ==s3.length
那麼如果繼續往下走,是成功的,我們可以返回true.
如果不成功,返回false就行啊 。
class Solution { boolean[][] visited; public boolean isInterleave( String s1, String s2, String s3 ) { if( s1.length()+s2.length()!=s3.length()) { return false; } visited = new boolean[s1.length()+1][s2.length()+1]; return backtract(s1,s2,s3,0,0,0); } public boolean backtract(String s1, String s2, String s3,int i,int j,int k) { // 跳出條件 if(i==s1.length()&&j==s2.length()&&k==s3.length()) { return true; } //為了防止計算過的計算, if(visited[i][j]) { return false; } visited[i][j]=true; // 如果按著i,k 往後移動走,而且這個方向還能走通,那麼就返回true; if(i<s1.length()&&s1.charAt(i)==s3.charAt(k)&&backtract(s1,s2,s3,i+1,j,k+1)) { return true; } // 如果按著j,k 往後移動的方向走,而且這個方向能走通,就返回true; if(j<s2.length()&&s2.charAt(j)==s3.charAt(k)&&backtract(s1,s2,s3,i,j+1,k+1)) { return true; } // 如果走不通嘛。肯定返回false了; return false; } }