字符串交错组成
题目描述:
对于三个字符串A,B,C。我们称C由A和B交错组成当且仅当C包含且仅包含A,B中所有字符,且对应的顺序不改变。请编写一个高效算法,判断C串是否由A和B交错组成。
给定三个字符串A,B和C,及他们的长度。请返回一个bool值,代表C是否由A和B交错组成。保证三个串的长度均小于等于100。
测试样例:
"ABC",3,"12C",3,"A12BCC",6
返回:true
分析思路:
构造一个(M+1)*(N+1)的矩阵dp:
- dp[0][0]=true.aim为空时可以由str1和str2的空字符串组成
- dp[i][0]表示aim[0…i-1]能否由str1[0……i-1]组成,若可以则dp[i][0]=true,反之则为false
- dp[0][j]表示aim[0…j-1]能否由str2[0……j-1]组成,若可以则dp[0][j]=true,反之则为false
- 其他位置(i,j),dp[i][j]的值:
dp[i-1][j]代表aim[i+j-2]能否被str1[0…i-2]和str2[0…j-1]交错组成,若可以,以及str1[i-1]等于aim[i+j-1],则dp[i][j]=true,反之则为false
dp[i][j-1]代表aim[i+j-2]能否被str1[0…i-1]和str2[0…j-2]交错组成,若可以,以及str2[j-1]等于aim[i+j-1],则dp[i][j]=true,反之则为false
若前两种情况都不满足,则dp[i][j]=false
代码实现
#include<bits/stdc++.h>
using namespace std;
class Solution
{
public:
bool isInterleave(string s1, string s2, string s3)
{
size_t len1, len2;
len1 = s1.length();
len2 = s2.length();
if (len1 + len2 != s3.length())
return false;
vector<vector<bool>> dp;//定义变量
dp.resize(len1 + 1, vector<bool>(len2 + 1, false));//分配空间
dp[0][0] = true;//aa ab aaba
for (int i = 0; i <= len1; i++)
for (int j = 0; j <= len2; j++)
{
if (i == 0 && j == 0)
continue;
if (i > 0) {
if (s1[i - 1] == s3[i + j - 1]) {
dp[i][j] = dp[i][j] || dp[i - 1][j];
}
}
if (j > 0) {
if (s2[j - 1] == s3[i + j - 1]) {
dp[i][j] = dp[i][j] || dp[i][j - 1];
}
}
}
bool result = dp[len1][len2];
return result;
}
};
int main()
{
Solution S;
string s1 = "aa";
string s2 = "ab";
string s3 = "aaba";
bool ans = S.isInterleave(s1, s2, s3);
if (ans) cout << "true" << endl;
else cout << "false" << endl;
return 0;
}