97. 交错字符串 - 力扣(LeetCode)
根据题意,就是组成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往后移动。
三个决策点对吧。
那么跳出条件是什么呢?
那么如果继续往下走,是成功的,我们可以返回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; } }