Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc"
,
s2 = "dbbca"
,
When s3 = "aadbbcbcac"
, return true.
When s3 = "aadbbbaccc"
, return false.
First, I wrote a DFS program using a stack, however, TLE
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int i = 0, j = 0, k = 0;
stack<int> s3stack, s2stack;
if (s1.length() + s2.length() != s3.length())
return false;
for (k = 0; k < s3.length(); ++k) {
if (i < s1.length() && s3[k] == s1[i]) {
if (j < s2.length() && s3[k] == s2[j]) {
s3stack.push(k);
s2stack.push(j);
}
++i;
}
else {
if (j < s2.length() && s3[k] == s2[j])
++j;
else {
if (s3stack.empty())
return false;
k = s3stack.top();
s3stack.pop();
j = s2stack.top();
s2stack.pop();
i = k -j;
++j;
}
}
}
if (i == s1.length() && j == s2.length())
return true;
else
return false;
}
};
After reading the solution from other people, I wrote a DP program, however, I can't simplify the DP matrix to dp[k][i] though many statuses are redundant.. So the following is the code:
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int i = 0, j = 0, k = 0;
if (s1.length() + s2.length() != s3.length())
return false;
vector<vector<vector<bool>>> dp(s3.length()+1, vector<vector<bool>> (s1.length()+1, vector<bool> (s2.length()+1, false)));
for (i = 0; i <= s1.length(); ++i)
for (j = 0; j <=s2.length(); ++j)
dp[0][i][j] = true;
int less = s1.length() < s2.length() ? s1.length() : s2.length();
for (k = 0; k <= less; ++k)
dp[k][0][k] = dp[k][k][0] = true;
for (k = 1; k <= s3.length(); ++k) {
int s1len = s1.length(), s2len = s2.length();
int start = max(0,k-s2len);
int end = min(k,s1len);
for (i = start; i <= end; ++i)
dp[k][i][k-i] = ((i>=1 && dp[k-1][i-1][k-i] && s3[k-1] == s1[i-1]) || (i<=k-1 && dp[k-1][i][k-i-1] && s3[k-1] == s2[k-i-1])) ? true : false;
}
return dp[s3.length()][s1.length()][s2.length()];
}
};
I made several mistakes:
1. The boundry: it's different for i>=1 and i <= k-1
2. You'd better use a variable to store s1.length() and s2.length(), the following code is wrong:
int start = (((k-s2.length()) > 0) ? (k-s2.length()) : 0);
but
int s2len = s2.length();
int start = (((k-s2len) > 0) ? (k-s2len) : 0);
is right.
So don't use s.length() for the operation
3.
vector<vector<vector<bool>>> dp(s3.length()+1, vector<vector<bool>> (s1.length()+1, vector<bool> (s2.length()+1, false)));