地址 https://leetcode-cn.com/problems/interleaving-string/
给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。
两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:
s = s1 + s2 + ... + sn
t = t1 + t2 + ... + tm
|n - m| <= 1
交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...
提示:a + b 意味着字符串 a 和 b 连接。
示例 1:
输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出:true
示例 2:
输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出:false
示例 3:
输入:s1 = "", s2 = "", s3 = ""
输出:true
提示:
0 <= s1.length, s2.length <= 100
0 <= s3.length <= 200
s1、s2、和 s3 都由小写英文字母组成
解答
题目应该是动态规划解法
但是我拿到题目觉得DFS各种匹配 也能一战
三个指针 a b c 分别指向三个字符串的首位
如果第一个字符串的当前字母能和第三个字符串的当前字母匹配 那么a c各加1,继续下一步尝试
如果第二个字符串的当前字母能和第三个字符串的当前字母匹配 那么b c各加1,继续下一步尝试
直到abc都到达三个字符串的末尾就是成功。
注意开始特判下,如果第三个字符串的长度不等于前两个字符串的长度和 那么直接false
TLE版本
class Solution {
public:
bool dfs(string s1, string s2, string s3, int a, int b, int c) {
if (a >= s1.size() && b >= s2.size() && c >= s3.size()) { return true; }
if (a < s1.size() && c < s3.size() && s1[a] == s3[c]) {
if (true == dfs(s1, s2, s3, a + 1, b, c + 1)) return true;
}
if (b < s2.size() && c < s3.size() && s2[b] == s3[c]) {
if (true == dfs(s1, s2, s3, a , b+1, c + 1)) return true;
}
return false;
}
bool isInterleave(string s1, string s2, string s3) {
if (s1.size() + s2.size() != s3.size()) return false;
int a = 0; int b = 0; int c = 0;
return dfs(s1, s2, s3, a, b, c);
}
};
果不其然,TLE了。
但是留意到大量的重复计算后
那么我们使用一个标记记录 a b c这三个索引的搜索已经搜索过 ,失败了。我们再次搜索a b c这种状态就直接返回失败就可以避免很多重复计算了
但是开一个三维数组int dp[][][] 需要100*100*200的空间 肯定超过空间要求了
所以我该用哈希记录
代码如下
class Solution {
public:
unordered_set<int> ss;
bool dfs(string s1, string s2, string s3, int a, int b, int c) {
if (a >= s1.size() && b >= s2.size() && c >= s3.size()) { return true; }
if (ss.count(a * 10000 + b * 100 + c) != 0) return false;
if (a < s1.size() && c < s3.size() && s1[a] == s3[c]) {
if (true == dfs(s1, s2, s3, a + 1, b, c + 1)) return true;
else{
ss.insert(a * 10000 + b * 100 + c);
}
}
if (b < s2.size() && c < s3.size() && s2[b] == s3[c]) {
if (true == dfs(s1, s2, s3, a , b+1, c + 1)) return true;
else {
ss.insert(a * 10000 + b * 100 + c);
}
}
return false;
}
bool isInterleave(string s1, string s2, string s3) {
if (s1.size() + s2.size() != s3.size()) return false;
int a = 0; int b = 0; int c = 0;
return dfs(s1, s2, s3, a, b, c);
}
};