八、interleaving-string
题目描述
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.
思路:定义一个二维存储空间,大小为(len_s1+1) x (len_s2+1),用来存储s3的前(i+j)个元素是否可由s1的前i个元素和s2的前j
个元素交叉得到。
class Solution {
public:
/*
类似于: 最长公共子序列问题;
flags[i][j] 表示取S1中的前i个数和取S2中的前j个数
flags[i][j] == true : 表示S3的前(i+j)长度的子串还是满足S1和S2交叉结合的
flags[i][j] == false: 表示不满足
首先我们来讲下直到S3前面(i+j)长度的子串还满足可以由S1和S2交叉构成的
条件是(flags[i][j-1] == true && S2[j-1] == S3[i+j-1] ) || ( flags[i-1][j] == true && S1[i-1] == S3[i+j-1] )
最后我们所要的结果就是当S1取S1.length长度,而S2取S2.length长度时,看是否满足,即flags[S1.length][S2.length]是否为true
*/
bool isInterleave(string s1, string s2, string s3) {
int len1=s1.length();
int len2=s2.length();
int len3=s3.length();
if((len1+len2)!=len3)
return false;
vector<vector<bool>> flag(len1+1,vector<bool>(len2+1,false));
flag[0][0]=true;
for(int i=1;i<=len1;i++)
{
flag[i][0]=flag[i-1][0]&&(s1[i-1]==s3[i-1]);
}
for(int j=1;j<=len2;j++)
{
flag[0][j]=flag[0][j-1]&&(s2[j-1]==s3[j-1]);
}
for(int i=1;i<=len1;i++)
{
for(int j=1;j<=len2;j++)
{
flag[i][j]=(flag[i-1][j]&&s1[i-1]==s3[i+j-1])||(flag[i][j-1]&&s2[j-1]==s3[i+j-1]);
}
}
return flag[len1][len2];
}
};
本地调试代码:
int main(){
string s1, s2, s3;
cin >> s1 >> s2 >> s3;
cout << isInterleave2(s1, s2, s3) << endl;
//cout << s1.substr(0, 0) << endl;
//cout << s1.substr(0, 0).size() << endl;
return 0;
}