动态规划
- 思路:
- 假设 dp[i][j] 是 s1 前 i 个元素和 s2 前 j 个元素能否交错构成 s3 的状态;
- 则其上一个状态有:
- dp[i - 1][j] 且 s1[i -1] == s3[i + j - 1] 条件决定了状态 dp[i][j];
- 或者 dp[i][j - 1] 且 s2[j - 1] == s3[i + j - 1] 条件决定了状态 dp[i][j];
- 边界条件 dp[0][0] = true;
- 所有以上的前提是 s1 与 s2 长度和是 s3 的长度;
- 注意边界情况 i = 0,j = 0 时,上一状态情况只有一种;
class Solution {
public:bool isInterleave(string s1, string s2, string s3) {int sz1 = s1.size();int sz2 = s2.size();int sz3 = s3.size();if (sz1 + sz2 != sz3) {return false;}auto dp = std::vector<std::vector<int>>(sz1 + 1, std::vector<int>(sz2 + 1, false));dp[0][0] = true;for (int i = 0; i <= sz1; ++i) {for (int j = 0; j <=sz2; ++j) {int k = i + j - 1;if (i > 0) {dp[i][j] |= (dp[i - 1][j] &&(s1[i - 1] == s3[k]));}if (j > 0) {dp[i][j] |= (dp[i][j - 1] && (s2[j - 1] == s3[k]));}}} return dp[sz1][sz2];}
};
- 将上面的代码换成之前(翻看专栏之前动态规划的文章)熟悉的模板步骤(待总结):
class Solution {
public:bool isInterleave(string s1, string s2, string s3) {int sz1 = s1.size();int sz2 = s2.size();int sz3 = s3.size();if (sz1 + sz2 != sz3) {return false;}auto dp = std::vector<std::vector<bool>>(sz1 + 1, std::vector<bool>(sz2 + 1, false));dp[0][0] = true;for (int i = 1; i <= sz1; ++i) {dp[i][0] = (dp[i - 1][0] && (s1[i - 1] == s3[i - 1]));}for (int j = 1; j <= sz2; ++j) {dp[0][j] = (dp[0][j - 1] && (s2[j - 1] == s3[j - 1]));}for (int i = 1; i <= sz1; ++i) {for (int j = 1; j <=sz2; ++j) {int k = i + j - 1;int con1 = (dp[i - 1][j] &&(s1[i - 1] == s3[k]));int con2 = (dp[i][j - 1] && (s2[j - 1] == s3[k]));dp[i][j] = (con1 || con2);}} return dp[sz1][sz2];}
};
- 好像可以用滚动数组来优化空间复杂度,待后面进一步研究;