题意:给定3个字符串s1,s2,s3,判断s3是否由s1和s2插入而成
思路:分我的思路和网上的思路,其实本质是一样的。
我的思路:用old1,old2数组表示上一个s3的字符能用s1和s2的哪些字符组成,new1,new2表示当前s3字母能由s1和s2组成,对于old数组的点对old1[i],old2[j],若s2[j+1]==s3[k],则在new的数组里push(i,j+1),同理若s1[i+1]==s3[k],则在new数组里push(i+1,j)。谨防重复的点对,可以用一个tag数组标记一下。
网上的思路:应对重复情况,把s1[0_l1]和s2[0_l2]看成一个二维的地图,如果s3[k]能由map(i,j)(即s1[0_i]和s2[0_j])组成,则如果s1[i+1]==s3[k+1],则map(i+1,j)为真;如果s2[j+1]==s3[k+1]的话,则map(i,j+1)为真。
本质一样的,只不过网上的思路更精妙,不用考虑重复点对的情形。
代码:
bool isInterleave(string s1, string s2, string s3)
{
int l1=s1.length(),l2=s2.length(),l3=s3.length(),i,j,c1,c2;
vector<int> old1,old2,new1,new2;
if(l3!=l1+l2||l1==0&&s2!=s3||l2==0&&s1!=s3) return false;
if(l1==0&&s2==s3||l2==0&&s1==s3) return true;
if(l3>0&&s3[0]!=s1[0]&&s3[0]!=s2[0]) return false;
if(s3[0]==s1[0])
{
old1.push_back(0);
old2.push_back(-1);
}
if(s3[0]==s2[0])
{
old1.push_back(-1);
old2.push_back(0);
}
for(i=1; i<l3; i++)
{
new1.clear();
new2.clear();
for(j=0; j<old1.size(); j++)
{
c1=old1[j];
c2=old2[j];
if(c2+1<l2&&s2[c2+1]==s3[i])
{
new1.push_back(c1);
new2.push_back(c2+1);
}
if(c1+1<l1&&s1[c1+1]==s3[i])
{
new1.push_back(c1+1);
new2.push_back(c2);
}
}
if(new1.size()==0) return false;
old1.clear();
old2.clear();
old1.push_back(new1[0]);
old2.push_back(new2[0]);
for(j=1; j<new1.size(); j++)
{
if(new1[j]!=new1[j-1])
{
old1.push_back(new1[j]);
old2.push_back(new2[j]);
}
}
}
return true;
}