LeetCode:97. Interleaving String
又一节约dp空间的例子:
首先是二维空间:
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int sz1 = s1.size(), sz2 = s2.size(), sz3 = s3.size();
if (sz3 != sz1 + sz2)
return false;
vector<vector<bool>> dp(sz1+1, vector<bool>(sz2+1, false));
dp[0][0] = true;
for (int i = 1; i < sz1 + 1; ++i)
dp[i][0] = ((s1[i-1] == s3[i-1]) && dp[i-1][0]);
for (int j = 1; j < sz2 + 1; ++j)
dp[0][j] = ((s2[j-1] == s3[j-1]) && dp[0][j-1]);
for (int i = 1; i < sz1 + 1; ++i)
for (int j = 1; j < sz2 + 1; ++j) {
dp[i][j] = (s1[i-1] == s3[i+j-1] && dp[i-1][j]) || (s2[j-1] == s3[i+j-1] && dp[i][j-1]);
//确实简洁好多啊
/*
int idx3 = i + j - 1;
if (s1[i-1] != s3[idx3] && s2[j-1] != s3[idx3])
dp[i][j] = false;
else if (s1[i-1] == s3[idx3] && s2[j-1] == s3[idx3])
dp[i][j] = dp[i-1][j] || dp[i][j-1];
else if (s1[i-1] == s3[idx3])
dp[i][j] = dp[i-1][j];
else
dp[i][j] = dp[i][j-1];
*/
}
return dp.back().back();
}
};
然后简化为一维:
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int sz1 = s1.size(), sz2 = s2.size(), sz3 = s3.size();
if (sz3 != sz1 + sz2)
return false;
vector<bool> dp(sz2+1);
dp[0] = true;
for (int j = 1; j < sz2+1; ++j) {
dp[j] = (s2[j-1] == s3[j-1]) && dp[j-1];
}
for (int i = 1; i < sz1+1; ++i)
for (int j = 0; j < sz2+1; ++j) {
if (j == 0)
dp[0] = s1[i-1] == s3[i-1] && dp[0];
else
dp[j] = (s1[i-1] == s3[i+j-1] && dp[j]) || (s2[j-1] == s3[i+j-1] && dp[j-1]);
}
return dp.back();
}
};
//确实类似这种只需要周围格子的dp可以节约空间
只要依赖的是最近的状态,就可以实现这种节省空间的操作。