【回溯DFS】【记忆化搜索】97.交错字符串
作者:互联网
根据题意,就是组成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;
}
}
标签:String,s3,s2,s1,往后,DFS,length,回溯,97 来源: https://www.cnblogs.com/coderpeng/p/16255579.html