题目:
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
Example 1:
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" Output: true
Example 2:
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" Output: false
解法一:DFS 回溯法(暴力搜索)
用例:(TLE)
"bbbbbabbbbabaababaaaabbababbaaabbabbaaabaaaaababbbababbbbbabbbbababbabaabababbbaabababababbbaaababaa"
"babaaaabbababbbabbbbaabaabbaabbbbaabaaabaababaaaabaaabbaaabaaaabaabaabbbbbbbbbbbabaaabbababbabbabaab"
"babbbabbbaaabbababbbbababaabbabaabaaabbbbabbbaaabbbaaaaabbbbaabbaaabababbaaaaaabababbababaababbababbb
ababbbbaaaabaabbabbaaaaabbabbaaaabbbaabaaabaababaababbaaabbbbbabbbbaabbabaabbbbabaaabbababbabbabbab"
代码如下:
class Solution {
public:
bool backtrace(string s1,string s2,string s3)
{
if(s1[0] == '\0' && s2[0] == '\0' && s3[0] =='\0')
{
return true;
}
if(s1[0] != s3[0] && s2[0] != s3[0])
return false;
if(s1[0] == s3[0] && s1[0] !='\0' && s2[0] != s3[0])
if(backtrace(s1.substr(1),s2,s3.substr(1)))
return true;
if(s1[0] != s3[0] && s2[0] == s3[0] && s2[0] != '\0')
if(backtrace(s1,s2.substr(1),s3.substr(1)))
return true;
if(s1[0] == s3[0] && s2[0] == s3[0])
{
if(backtrace(s1.substr(1),s2,s3.substr(1)) || backtrace(s1,s2.substr(1),s3.substr(1)))
return true;
}
return false;
}
bool isInterleave(string s1, string s2, string s3) {
return backtrace(s1,s2,s3);
}
};
解法二:对解法一进行了优化,增减了memo[s1.length()][s2.length()] ,如果值 >= 0, 则说明已经计算过,直接使用计算过的值,节省了重复计算的时间
class Solution {
public:
bool backtrace(string s1,int i,string s2,int j,string s3,int k,vector<vector<int> > &memo)
{
if(i == s1.length())
return s2.substr(j) == s3.substr(k);
if(j == s2.length())
return s1.substr(i) == s3.substr(k);
if(memo[i][j] >= 0)
return memo[i][j] == 1 ? true : false;
bool ans = false;
if((s3[k] == s1[i] && backtrace(s1,i+1,s2,j,s3,k+1,memo)) ||
(s3[k] == s2[j] && backtrace(s1,i,s2,j+1,s3,k+1,memo)))
{
ans = true;
}
memo[i][j] = ans ? 1 : 0;
return ans;
}
bool isInterleave(string s1, string s2, string s3) {
vector<vector<int> > memo(s1.length(),vector<int>(s2.length(),-1));
return backtrace(s1,0,s2,0,s3,0,memo);
}
};
解法三:BFS + queue + visited
queue只存储匹配的 i,j visited标记已经访问过的i,j
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
if(s1.length() + s2.length() != s3.length())
return false;
vector<vector<bool> > visited(s1.length() + 1, vector<bool>(s2.length()+1,false));
queue<vector<int> > Q;
vector<int> vi = {0,0};
Q.push(vi);
while(!Q.empty())
{
vector<int> p = Q.front();
Q.pop();
if(visited[p[0]][p[1]])
continue;
if(p[0] == s1.length() && p[1] == s2.length())
return true;
if(p[0] < s1.length() && s1[p[0]] == s3[p[0] + p[1]])
{
vector<int> v1 = {p[0] + 1, p[1]};
Q.push(v1);
}
if(p[1] < s2.length() && s2[p[1]] == s3[p[0] + p[1]])
{
vector<int> v2 = {p[0],p[1] + 1};
Q.push(v2);
}
visited[p[0]][p[1]] = true;
}
return false;
}
};
解法四:动态规划
bool isInterleave(string s1, string s2, string s3) {
if(s3.length() != s1.length() + s2.length())
return false;
bool table[s1.length()+1][s2.length()+1];
for(int i=0; i<s1.length()+1; i++)
for(int j=0; j< s2.length()+1; j++){
if(i==0 && j==0)
table[i][j] = true;
else if(i == 0)
table[i][j] = ( table[i][j-1] && s2[j-1] == s3[i+j-1]);
else if(j == 0)
table[i][j] = ( table[i-1][j] && s1[i-1] == s3[i+j-1]);
else
table[i][j] = (table[i-1][j] && s1[i-1] == s3[i+j-1] ) || (table[i][j-1] && s2[j-1] == s3[i+j-1] );
}
return table[s1.length()][s2.length()];
}