Leetcode 97. 交错字符串 dfs+记忆化搜索

地址 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);
	}
};

我的视频题解空间

作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
阿里打赏 微信打赏
原文地址:https://www.cnblogs.com/itdef/p/14813055.html