Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc" ,
s2 = "dbbca" ,
When s3 = "aadbbcbcac" , return true .
When s3 = "aadbbbaccc" , return false .
这道题目比较有难度。当然用递归的方法比较简单,但是会出现超时的问题,非递归用dp比较有难度,不太容易想明白递归公式。
递归方法:
bool isInterleave(char * s1, char * s2, char * s3) {
int n1 = strlen (s1);
int n2 = strlen (s2);
int n3 = strlen (s3);
if ((n1+n2)!=n3){
return false ;
}
if (n3 == 0 && n1 == 0 && n2 == 0 ){
return true ;
}
if (s1[0 ] != s3[0 ] && s2[0 ] != s3[0 ]){
return false ;
}
if (s1[0 ] != '\0' && s1[0 ] == s3[0 ] && s2[0 ]!=s3[0 ]){
return isInterleave(s1+1 ,s2,s3+1 );
}
if (s2[0 ] != '\0' && s1[0 ] != s3[0 ] && s2[0 ]==s3[0 ]){
return isInterleave(s1,s2+1 ,s3+1 );
}
if (s1[0 ] == s3[0 ] && s2[0 ] == s3[0 ]){
return isInterleave(s1,s2+1 ,s3+1 )||
isInterleave(s1+1 ,s2,s3+1 );
}
return true ;
}
非递归方法
class Solution {
public :
bool isInterleave(string s1, string s2, string s3) {
int n1 = s1.size();
int n2 = s2.size();
int n3 = s3.size();
vector <bool > t(n2+1 ,false );
vector <vector <bool > > dp(n1+1 ,t);
if (n1+n2 != n3){
return false ;
}
for (int i = 0 ; i <= n1; ++i){
for (int j = 0 ; j<= n2; ++j){
if (i == 0 && j == 0 ){
dp[i][j] = true ;
}else if (i == 0 ){
dp[i][j] = dp[i][j-1 ] && s2[j-1 ] == s3[i+j-1 ];
}else if (j == 0 ){
dp[i][j] = dp[i-1 ][j] && s1[i-1 ] == s3[i+j-1 ];
}else {
dp[i][j] = (dp[i][j-1 ] && s2[j-1 ] == s3[i+j-1 ])||(dp[i-1 ][j] && s1[i-1 ] == s3[i+j-1 ]);
}
}
}
return dp[n1][n2];
}
};