Given three strings: s1, s2, s3, determine whether s3 is formed by the interleaving of s1 and s2.

一句比较经典的话

“When you see string problem that is about subsequence or matching, dynamic programming method should come to your mind naturally. ”

跟 ​​lintcode: Distinct Subsequences​​ 类似。

用res[i][j] 表示s1的前i个字母和s2的前j个字母是否可以跟s3的前i+j个字母匹配。

还用走二维地图的方式解释

lintcode: Interleaving String_递推公式


相当于从图中左上角的红圈走到右下角的红圈。

很显然只能往右和往下走。

当res[i-1][j] ==true且 s1[i-1]==s3[i+j-1] 时,说明从上面往下走到的;

当res[i][j-1] ==true且 s2[j-1]==s3[i+j-1]时,说明从左边往右走到的;

所以递推公式是:

res[i][j]=( res[i-1][j]&& s1[i-1]==s3[i+j-1] ) || (res[i][j-1] && s2[j-1]==s3[i+j-1]);
class Solution {
public:
/**
* Determine whether s3 is formed by interleaving of s1 and s2.
* @param s1, s2, s3: As description.
* @return: true of false.
*/
bool isInterleave(string s1, string s2, string s3) {
// write your code here
int len1=s1.size();
int len2=s2.size();

if(len1+len2!=s3.size()){
return false;
}

vector<vector<bool> > res(len1+1,vector<bool>(len2+1,false));

res[0][0]=true;

for(int i=1;i<=len1;i++){
if(s1[i-1]==s3[i-1]){
res[i][0]=true;
}
}

for(int j=1;j<=len2;j++){
if(s2[j-1]==s3[j-1]){
res[0][j]=true;
}
}


for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
res[i][j]=( res[i-1][j]&& s1[i-1]==s3[i+j-1] ) ||
(res[i][j-1] && s2[j-1]==s3[i+j-1]);
}
}

return res[len1][len2];
}
};