思路:
动态规划. 依然是开辟一个矩阵, 先初始化第一列和第一行, 然后补充剩下的格子. 思路主要是每次考虑两条路, 一个是s3的当前字符和s1的当前字符等, 且s1上一个字符所对应的格子也是真; 第二种情况是s3的当前字符是否和s2的当前字符等, 且s2上一个字符所对应的格子也是真.
同理, 可以把空间缩小为O(n)的, 因为我们最多用到上一次递归的结果, 所以空间大小n即可.
bool isInterleave(string s1, string s2, string s3) {
int len1 = s1.length();
int len2 = s2.length();
int len3 = s3.length();
if (len3 != len1 + len2)
return false;
bool flags[len1 + 1][len2 + 1];
flags[0][0] = true;
for (int i = 1; i <= len1; i++)
flags[i][0] = flags[i - 1][0] && s1[i - 1] == s3[i - 1];
for (int j = 1; j <= len2; j++)
flags[0][j] = flags[0][j - 1] && s2[j - 1] == s3[j - 1];
for (int i = 1; i <= len1; i++)
for (int j = 1; j <= len2; j++)
flags[i][j] = flags[i - 1][j] && s1[i - 1] == s3[i + j - 1]
|| flags[i][j - 1] && s2[j - 1] == s3[i + j - 1];
return flags[len1][len2];
}
bool isInterleave(string s1, string s2, string s3) {
int len1 = s1.length();
int len2 = s2.length();
int len3 = s3.length();
if (len1 > len2) return isInterleave(s2, s1, s3);
if (len3 != len1 + len2)
return false;
bool flags[len2 + 1];
flags[0] = true;
for (int j = 1; j <= len2; j++)
flags[j] = flags[j - 1] && s2[j - 1] == s3[j - 1];
for (int i = 1; i <= len1; i++) {
flags[0] = flags[0] && s1[i - 1] == s3[i - 1];
for (int j = 1; j <= len2; j++)
flags[j] = flags[j] && s1[i - 1] == s3[i + j - 1]
|| flags[j - 1] && s2[j - 1] == s3[i + j - 1];
}
return flags[len2];
}