1、题目
给定s1,s2,s3,找出s3是否由s1和s2的交织形成。 例如, 鉴于: s1 =“aabcc”, s2 =“dbbca”, 当s3 =“aadbbcbcac”时,返回true。 当s3 =“aadbbbaccc”时,返回false。
2、分析过程
动态规划: dp[i][j] 表示 s2 的前 i 个字符和 s1 的前 j 个字符是否匹配 s3 的前 i+j 个字符。 初始化dp[0][0]=0,dp[0][j]表示s2取0个,即s1的前j个字符是否匹配s3的前j个字符;dp[i][0]表示s1取0个,即s2的前i个字符,是否匹配s3的前i个字符。 动规方程:dp[i][j] = dp[i - 1][j] && s2[i - 1] == s3[i + j - 1] || dp[i][j - 1] && s1[i][j - 1] == s3[i + j - 1] ,意思是如果s2的前i-1个字符和s1的前j个字符已经和s3的前i+j-1个字符匹配且s2的第i个字符等于s3的第i+j个字符,或者s2的前i个字符和s1的前j-1个字符已经和s3的前i+j-1个字符匹配,且s1的第j个字符等于s3的第i+j个字符,那么s2的前i个字符和s1的前j个字符能否与s3的前i+j-1个字符匹配。
3、代码实现
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if(s1==null || s2==null || s3==null || s1.length()+s2.length()!=s3.length()){
return false;
}
int n1=s1.length();
int n2=s2.length();
int n3=s3.length();
boolean [][] dp=new boolean [n1+1][n2+1];//dp[i][j]表示s1中的前i个字符和s2的前j个字符是否能组成s3的前i+j个字符
//初始化dp数组
dp[0][0]=true;
for(int i=1;i<=n1;i++){
if(dp[i-1][0] && s1.charAt(i-1)==s3.charAt(i-1)){
dp[i][0] =true;
}else{
dp[i][0]=false;
}
}
for(int i=1;i<=n2;i++){
if(dp[0][i-1] && s2.charAt(i-1)==s3.charAt(i-1)){
dp[0][i] =true;
}else{
dp[0][i]=false;
}
}
for(int i=1;i<=n1;i++){
for(int j=1;j<=n2;j++){
if(dp[i-1][j]){
if(s1.charAt(i-1)==s3.charAt(i+j-1)){
dp[i][j]=true;
}
}else if(dp[i][j-1]){
if(s2.charAt(j-1)==s3.charAt(i+j-1)){
dp[i][j]=true;
}
}else{
dp[i][j]=false;
}
}
}
return dp[n1][n2];
}
}
题目来自:牛客网leetCode