题目
给定三个字符串 s 1 、 s 2 、 s 3 s1、s2、s3 s1、s2、s3,请你帮忙验证 s 3 s3 s3 是否是由 s 1 s1 s1 和 s 2 s2 s2 交错 组成的。
两个字符串 s s s 和 t t t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:
- s = s 1 + s 2 + . . . + s n s = s1 + s2 + ... + sn s=s1+s2+...+sn
- t = t 1 + t 2 + . . . + t m t = t1 + t2 + ... + tm t=t1+t2+...+tm
- ∣ n − m ∣ < = 1 |n - m| <= 1 ∣n−m∣<=1
- 交错 是 s 1 + t 1 + s 2 + t 2 + s 3 + t 3 + . . . s1 + t1 + s2 + t2 + s3 + t3 + ... s1+t1+s2+t2+s3+t3+... 或者 t 1 + s 1 + t 2 + s 2 + t 3 + s 3 + . . . t1 + s1 + t2 + s2 + t3 + s3 + ... t1+s1+t2+s2+t3+s3+...
方法
- 动态规划
- s 1 、 s 2 、 s 3 s1、s2、s3 s1、s2、s3 长度分别为 n 1 、 n 2 、 n n1、n2、n n1、n2、n
- 定义 d p n 1 + 1 , n 2 + 2 dp_{n1+1,n2+2} dpn1+1,n2+2 数组, d p [ i ] [ j ] dp[i][j] dp[i][j] 表示 s 3 s3 s3 前 i + j i+j i+j 个字符是否由 s 1 s1 s1 前 i i i 个字符和 s 2 s2 s2 前 j j j 个字符交错组成
- 若 s 3 [ i + j − 1 ] = = s 1 [ i − 1 ] s3[i+j-1] == s1[i-1] s3[i+j−1]==s1[i−1],则 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j] = dp[i-1][j] dp[i][j]=dp[i−1][j]
- 若 s 3 [ i + j − 1 ] = = s 2 [ j − 1 ] s3[i+j-1] == s2[j-1] s3[i+j−1]==s2[j−1],则 d p [ i ] [ j ] = d p [ i ] [ j − 1 ] dp[i][j] = dp[i][j-1] dp[i][j]=dp[i][j−1]
- 空间复杂度优化:滚动数组
- 定义 d p n 2 + 2 dp_{n2+2} dpn2+2 数组
- d p [ j ] dp[j] dp[j] 上一次循环的值表示原来的 d p [ i − 1 ] [ j ] dp[i-1][j] dp[i−1][j]
代码
class Solution {
public:
// bool isInterleave(string s1, string s2, string s3) {
// int n1 = s1.size();
// int n2 = s2.size();
// int n = s3.size();
// if(n1+n2 != n)
// return false;
// vector<vector<bool>> dp(n1+1, vector<bool>(n2+1));
// dp[0][0] = true;
// for(int i = 0; i <= n1; i++){
// for(int j = 0; j <= n2; j++){
// if(i > 0){
// dp[i][j] = dp[i][j] || (dp[i-1][j] && s1[i-1] == s3[i+j-1]);
// }
// if(j > 0){
// dp[i][j] = dp[i][j] || (dp[i][j-1] && s2[j-1] == s3[i+j-1]);
// }
// }
// }
// return dp[n1][n2];
// }
bool isInterleave(string s1, string s2, string s3) {
int n1 = s1.size();
int n2 = s2.size();
int n = s3.size();
if(n1+n2 != n)
return false;
vector<bool> dp(n2+1);
dp[0] = true;
for(int i = 0; i <= n1; i++){
for(int j = 0; j <= n2; j++){
if(i > 0){
dp[j] = (dp[j] && s1[i-1] == s3[i+j-1]);
}
if(j > 0){
dp[j] = dp[j] || (dp[j-1] && s2[j-1] == s3[i+j-1]);
}
}
}
return dp[n2];
}
};