题目描述:
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.
这个题一开始用的是dfs,超时了:
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int n1=s1.length(),n2=s2.length(),n3=s3.length();
if(n1+n2!=n3){
return false;
}
if(n3==0)
return true;
int i=n1-1,j=n2-1,k=n3-1;
if(i>=0&&s1.charAt(i)==s3.charAt(k)&&(j==-1||s2.charAt(j)!=s3.charAt(k))){
return isInterleave(s1.substring(0,i), s2, s3.substring(0,k));
}
if(j>=0&&s2.charAt(j)==s3.charAt(k)&&(i==-1||s1.charAt(i)!=s3.charAt(k))){
return isInterleave(s1, s2.substring(0,j), s3.substring(0,k));
}
if(i>=0&&s1.charAt(i)==s3.charAt(k)&&j>=0&&s2.charAt(j)==s3.charAt(k)){
return isInterleave(s1.substring(0,i), s2, s3.substring(0,k))||isInterleave(s1, s2.substring(0,j), s3.substring(0,k));
}
return false;
}
}
这个题应该用动态规划算法,dp[i][j]表示用s1的前i个字符和s2的前j个字符能不能按照规则表示出s3的前i+j个字符,如此最后结果就是dp[s1.length()][s2.length()],判断是否为真即可。public class Solution {
boolean dp[][];
public boolean isInterleave(String s1, String s2, String s3){
int size1 = s1.length();
int size2 = s2.length();
int size3 = s3.length();
if( size1 + size2 != size3) return false;
dp=new boolean[size1+1][size2+1];
dp[0][0] = true;
for(int i = 1; i <= size1; ++i)
if(s1.charAt(i-1) == s3.charAt(i-1)) dp[i][0] = true;
else break;
for(int j = 1; j <= size2; ++j)
if(s2.charAt(j-1) == s3.charAt(j-1)) dp[0][j] = true;
else break;
int k;
for(int i = 1; i <= size1; ++i)
for(int j = 1; j <= size2; ++j)
{
k = i + j;
if(s1.charAt(i-1) == s3.charAt(k-1)) dp[i][j] = dp[i-1][j] || dp[i][j];
if(s2.charAt(j-1) == s3.charAt(k-1)) dp[i][j] = dp[i][j-1] || dp[i][j];
}
return dp[size1][size2];
}
}