交错字符串
Solution
这题的状态定义比较巧妙,dp是一个bool类型的数组,dp(i,j)表示s1的前i个字符加上s2的前j个字符是否能够交错形成s3的前i+j个字符。
考虑dp(i,j),当前处于s3的第i+j-1个字符,这个字符有两种可能的来源,可能来自于s1的第i个字符,也可能来自于s2的第j个字符,如果这三个字符都相等,则在两种情况中取一种情况即可,也就是取或。


cpp
#include<iostream>
#include<vector>
using namespace std;
//dp做法
bool f1(string s1, string s2, string s3) {
int n1 = s1.length();
int n2 = s2.length();
//dp(i,j)表示s1的前i个字符与s2的前j个字符是否能组成s3的前i+j个字符
vector<vector<bool>>dp(n1 + 1, vector<bool>(n2 + 1, false));
if (n1 + n2 != s3.length()) return false;
//base case
dp[0][0] = true;
for (int i = 1; i <= n1; ++i) {
if (s1[i - 1] == s3[i - 1])
dp[i][0] = true;
else
break;
}
for (int j = 1; j <= n2; ++j) {
if (s2[j - 1] == s3[j - 1])
dp[0][j] = true;
else break;
}
for (int i = 1; i <= n1; ++i) {
for (int j = 1; j <= n2; ++j) {
if (s1[i - 1] == s3[i + j - 1] && s2[j - 1] == s3[i + j - 1])
dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
else if (s1[i - 1] == s3[i + j - 1] && s2[j - 1] != s3[i + j - 1])
dp[i][j] = dp[i - 1][j];
else if (s1[i - 1] != s3[i + j - 1] && s2[j - 1] == s3[i + j - 1])
dp[i][j] = dp[i][j - 1];
}
}
return dp[n1][n2];
}
//dp+空间压缩
bool f2(string s1, string s2, string s3) {
int n1 = s1.length();
int n2 = s2.length();
int n3 = s3.length();
if (n1 + n2 != n3) return false;
vector<int>dp(n2 + 1, false);
dp[0] = true;
for (int i = 0; i <= n1; ++i) {
for (int j = 0; j <= n2; ++j) {
int p = i + j - 1;
if (i > 0) {
dp[j] &= (s1[i - 1] == s3[p]);
}
if (j > 0) {
dp[j] |= (dp[j - 1] && s2[j - 1] == s3[p]);
}
}
}
return dp[n2];
}
bool isInterleave1(string s1, string s2, string s3) {
return f1(s1, s2, s3);
}
bool isInterleave(string s1, string s2, string s3) {
return f2(s1, s2, s3);
}
int main() {
return 0;
}