其实这种两个字符串的操作题比较多,很多都是可以借助DP解决的,比较经典的题就比如:距离编辑
废话不多,dp[i][j]定义为s1的前i项以及s2前j项共同交叉组成了s3的前i+j项的可能性,只有满足组成条件时次可以设dp[i][j]=true
转移方程: i!=0&&j!=0: dp[i][j]=(dp[i-1][j]&&(s1[i-1]==s3[i+j-1])) || (dp[i][j-1]&& (s2[j-1]==s3[i+j-1]))
i=0&&j!=0: dp[0][i]=s2.substr(0,i)==s3.substr(0,i)
i!=0&& j=0: dp[i][0]=s1.substr(0,i)==s3.substr(0,i)
AC code:
/**
dp[i][j]: use s1[0...i-1] and s2[0...j-1] to form s3[0...i+j-1]
dp[i][j]=1 when dp[i-1][j]=1 && s1[i]=s3[i+j-1]
or dp[i][j-1]=1 && s2[j]=s3[i+j-1]
**/
class Solution
{
public:
bool isInterleave(string s1, string s2, string s3)
{
int len1=s1.size(),len2=s2.size(),len3=s3.size();
if((len1+len2)!=len3)
return 0;
if(len1==0)
return s2==s3;
if(len2==0)
return s1==s3;
vector< vector<bool> > dp(s1.size()+5,vector<bool>(s2.size()+5,0));
//init
dp[0][0]=true;
for(int i=1;i<=len1;i++)
dp[i][0]=s1.substr(0,i)==s3.substr(0,i);
for(int i=1;i<=len2;i++)
dp[0][i]=s2.substr(0,i)==s3.substr(0,i);
for(int i=1;i<=len1;i++)
for(int j=1;j<=len2;j++)
dp[i][j]=(dp[i-1][j]&&(s1[i-1]==s3[i+j-1]))
||(dp[i][j-1]&& (s2[j-1]==s3[i+j-1]));
return dp[len1][len2];
}
};