zoukankan      html  css  js  c++  java
  • 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驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法
    自学PHP 环境搭建
    Postfix+Amavisd-new+Spamassassin+ClamAV整合安装
    安装Apache Felix OSGI Framework小记
    C#多线程
    使用maven进行测试设置断点调试的方法
    2016第33周四
    Spring配置文件头及xsd文件版本
    2016第33周二
    web中的重定向与转发
  • 原文地址:https://www.cnblogs.com/itdef/p/14813055.html
Copyright © 2011-2022 走看看