97. Interleaving String
topic
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.
Topic Analysis
There are three strings in this question, and string 3 is formed by alternating strings 1 and 2. When I saw this topic, I thought of a search that searches for string 3 in the sequence of strings 1 and 2. Quickly write the following code:
class Solution {
public:
bool solve(string s1, string s2, string s3, int idx1, int idx2, int idx)
{
if (idx == s3.size())
return true;
bool f = false;
if (idx1<s1.size() && s1[idx1] == s3[idx])
{
f = f || solve(s1, s2, s3, idx1 + 1, idx2, idx + 1);
}
if (idx2<s2.size() && s2[idx2] == s3[idx])
{
f = f || solve(s1, s2, s3, idx1, idx2 + 1, idx + 1);
}
return f;
}
bool isInterleave(string s1, string s2, string s3) {
if (s1.size() + s2.size() != s3.size())
return false;
return solve(s1, s2, s3, 0, 0, 0);
}
};
Tragically, however, it times out at the 99th instance. There must be some repetition.
s1 = "bbbbbabbbbabaababaaaabbababbaaabbabbaaabaaaaababbbababbbbbabbbbababbabaabababbbaabababababbbaaababaa";
s2 = "babaaaabbababbbabbbbaabaabbaabbbbaabaaabaababaaaabaaabbaaabaaaabaabaabbbbbbbbbbbabaaabbababbabbabaab";
s3 = "babbbabbbaaabbababbbbababaabbabaabaaabbbbabbbaaabbbaaaaabbbbaabbaaabababbaaaaaabababbababaababbababbbababbbbaaaabaabbabbaaaaabbabbaaaabbbaabaaabaababaababbaaabbbbbabbbbaabbabaabbbbabaaabbababbabbabbab";
memo method
Take a closer look at this test case. In this case where there are only two characters, if the original search is used, it will often enter recursion when judging whether the characters are equal, and the same position will be searched many times. There are many repeated search parts. Caused a timeout, so I thought of using the memorandum method. The improvement is as follows, it is AC~
class Solution {
public:
bool solve(string s1, string s2, string s3, int idx1, int idx2, int idx, vector<vector<int>> &dp)
{
if (idx == s3.size())
return true;
if (dp[idx1][idx2] != -1) // 已经搜索过这个位置
{
if (dp[idx1][idx2] == 1)
return true;
return false;
}
bool f = false;
if (idx1 < s1.size() && s1[idx1] == s3[idx])
{
f = f || solve(s1, s2, s3, idx1 + 1, idx2, idx + 1,dp);
}
if (idx2 < s2.size() && s2[idx2] == s3[idx])
{
f = f || solve(s1, s2, s3, idx1, idx2 + 1, idx + 1,dp);
}
dp[idx1][idx2] = f;
return f;
}
bool isInterleave(string s1, string s2, string s3) {
int len1 = s1.size();
int len2 = s2.size();
vector<vector<int>> f(len1+1, vector<int>(len2+1, -1));
if (s1.size() + s2.size() != s3.size())
return false;
return solve(s1, s2, s3, 0, 0, 0,f);
}
};
In the future, when doing this kind of search questions, you should think carefully about whether there are repetitions and avoid detours.
Corrections are welcome.