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搜索,然后往上提交直接超时。只能换个思路,其实还是一个典型的动态规划问题了。主要是找状态转移方程,例如:s3的前面aadbb这个如果能被s1和s2字串交叉组成,必然是s1的前j个和s2的前k=strlen(aadbb)-j个交叉组成的。同时必然是s1或s2字串的最后一个字母==‘b’;于是就容易找到状态方程了。即,两种情况,
1) 如果s1[j]==s3[i] 同时 s1[0~~j-1]和s2[0~~k]能组成s3[0~~i-1].那么s1[0~~j]和s2[0~~k]能组成s3[0~~i].
2) 如果s2[k]==s3[i] 同时s2[0~~k-1]和s1[0~~j]能组成s3[0~~i-1].那么s1[0~~j]和s2[0~~k]能组成s3[0~~i].
class Solution { public: bool isInterleave(string s1, string s2, string s3) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. int len1=s1.size(),len2=s2.size(),len3=s3.size(); if(len1+len2!=len3) return false; bool flag[len1+1][len2+1]; for(int i=0;i<=len1;i++) for(int j=0;j<=len2;j++) flag[i][j]=false; flag[0][0]=true; for(int i=0;i<len1;i++) { if(s3[i]==s1[i]) flag[i+1][0]=true &&flag[i][0]; } for(int i=0;i<len2;i++) { if(s3[i]==s2[i]) flag[0][i+1]=true &&flag[0][i]; } for(int i=1;i<len3;i++) { for(int j=1;j<i+1 &&j<=len1;j++) { int k=i+1-j; if(flag[j][k-1] && s2[k-1]==s3[i]) flag[j][k]=true; if(flag[j-1][k] && s1[j-1]==s3[i]) flag[j][k]=true; } } return flag[len1][len2]; }
第一次做的时候想写dp,发现很容易写dfs就直接写了。题目也没有告诉字符串长度会是多少,没有范围怎么考虑用哪种方法。。。。
发现做dp,能快速找到状态转移方程,代码都很短。
最后吐槽下实习的事情,有个还算牛x公司。去投了简历不知能不能给个实习机会啊。