模拟自己正常的思维过程
选取 s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac” 为样例
-
选s3的第1个a, 然后分别拿s1的第1个和s2的第1个做比较,发现s1的第1个匹配。
-
选s3的第2个a, 然后分别拿s1的第2个和s2的第1个做比较,发现s1的第2个匹配。这时候幡然醒悟,需要加两个指针指向iS1 和iS2的当前位置。
-
所以重来: 选s3的第1个a, 然后分别拿s1的第1个和s2的第1个做比较,发现s1的第1个匹配。iS1++;
-
选s3的第2个a, 然后分别拿s1的第2个和s2的第1个做比较,发现s1的第2个匹配。iS1++;
-
选第s3的第n个 (0<n<=s1.length()),如果s1.charAt(iS1)匹配那就去选s3的n+1个继续匹配并且iS1+1。如果s2.charAt(iS2)匹配那就去选s3的n+1个继续匹配并且iS2+1。转换成代码如下
if(iS2<s2.length()&&s2.charAt(iS2)==s3.charAt(iS2+iS3)){ dp(s2, s3, s1, iS2+1, iS3); } if(iS1<s1.length()&&s1.charAt(iS1)==s3.charAt(iS2+iS3)){ dp(s2, s3, s1, iS2, iS3+1); }
那么整体的暴力递归代码如下
public boolean dp(String s2,String s3,String s1,int iS2,int iS1){
if(iS2+iS1==s3.length()){
return true;
}
boolean t1=false;
boolean t2=false;
if(iS2<s2.length()&&s2.charAt(iS2)==s1.charAt(iS2+iS1)){
t1=dp(s2, s3, s1, iS2+1, iS1);
}
if(iS1<s1.length()&&s1.charAt(iS1)==s1.charAt(iS2+iS1)){
t2=dp(s2, s3, s1, iS2, iS1+1);
}
return t1||t2;
}
加上记忆化搜索进行优化
//visited 有三种值,0代表没访问 1代表访问,但是为false ,2代表访问并且为true
public boolean dp(String s2,String s3,String s1,int iS2,int iS1,int[][] visited){
if(iS2+iS1==s3.length()){
return true;
}
boolean t1=false;
boolean t2=false;
if(iS2<s2.length()&&s2.charAt(iS2)==s1.charAt(iS2+iS1)){
if(visited[iS2+1][iS1]==0){
t1=dp(s2, s3, s1, iS2+1, iS1,visited);
visited[iS2+1][iS1]= t1==true?2:1;
}else {
t1=visited[iS2+1][iS1]==1?false:true;
}
}
if(iS1<s1.length()&&s1.charAt(iS1)==s1.charAt(iS2+iS1)){
if(visited[iS2][iS1+1]==0){
t2=dp(s2, s3, s1, iS2, iS1+1,visited);
visited[iS2][iS1+1]= t2==true?2:1;
}else {
t2=visited[iS2][iS1+1]==1?false:true;
}
}
return t1||t2;
}
就可以过leetcode了
动态规划
根据暴力递归的样式,我是很快的反应出来了跟机器人类似(机器人每次只能走下或者右)。
正常的动态规划的步骤
-
确定状态:dp(i,j) s3的前i+j个元素是否可以交错而成.(s1的前i个元素和s2的前j个元素)
-
递推公式: dp(i,j)=dp(i-1,j)||dp(i,j-1)
-
基础case:d(0,0)=true
-
代码
public boolean isInterleave(String s1, String s2, String s3) { if(s3.length()!=s2.length()+s1.length()){ return false; } boolean[][] dp=new boolean[s1.length()+1][s2.length()+1]; for (int i=0;i<s1.length()+1;i++){ for (int j=0;j<s2.length()+1;j++){ if(i==0&&j==0){ dp[i][j]=true; continue; } if(i>0&&s1.charAt(i-1)==s3.charAt(i+j-1)){ if(dp[i-1][j]){ dp[i][j]=true; } } if(j>0&&s2.charAt(j-1)==s3.charAt(i+j-1)){ if(dp[i][j-1]){ dp[i][j]=true; } } } } return dp[s1.length()][s2.length()]; }