每日一解 交错字符串(不算困难的动态规划)

博客探讨了如何验证一个字符串是否由两个其他字符串交错组成,通过动态规划的方法解决这个问题。给出了具体的示例和匹配过程,并提供了代码实现,强调了在匹配过程中需要考虑的情况和边界条件处理。
摘要由CSDN通过智能技术生成

标题 交错字符串

给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。

示例 1:
输入: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac”
输出: true

示例 2:
输入: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbbaccc”
输出: false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/interleaving-string

思路

第一反应自然是觉得用几个指针就可以很好地处理了。三个指针分别从三个字符串的初始往后走,遇到S1和S2当前的字母都不能和S3匹配的情况,就返回false。感觉时间复杂度是O(n),空间复杂度为常数,完全可以接受,那就按照这个思路先编码。
于是果不其然发现了思路的漏洞。例如出现使用"cc"和"ca"去匹配"cacc"的情况。那么一定是先匹配了ca再匹配cc。倘若先匹配了cc中的第一个c,那么接下来会发现无法匹配,返回false。事实上正确答案应该是true。
那么针对这种情况,很明显还是要是用动态规划来解决问题。我个人在思考匹配模式的时候,想到了采用如下的(N + 1) ✖ (M + 1)表格来及进行求解(N和M分别为s1和s2的长度):
表中的例子为示例1中的S1 = aabcc,S2 = dbbca, 求解目标字符串S3 = aadbbcbcac。表中第一行为S1,第一列为S2。

a a b c c
0 1 2 2 2 2
d 0 1 3 4 4 4
b 0 1 4 5 5 5
b 0 1 5 6 7 8
c 0 1 5 7 8 8
a 1 2 5 7 9 10

表中的数字是在该行该列的字符串情况下能匹配到的最大长度。
就用表中标记出来的4和7作为例子,
先看4:4上方的3大于左侧的1,那么说明接下来要匹配的是左侧的b,然后发现S3[3]为b,可以匹配,那么将该格置为3 + 1 = 4。即aa和db可以匹配到原表中的第4个字母。
然后看7,7左侧的6大于上方的5,那么说明接下来要匹配的是上方的c,然后发现S3[7]为c,可以匹配,那么将该格置为6 + 1 = 7。即aabc和dbb可以匹配到原表中的第7个字母。
最终可以发现表末的字母为10,正好是S3的长度,则认为匹配成功,可以满足要求。如果不足10,那么说明不可以匹配(注意表中加粗斜体的2,事实上是不能如此匹配的‘使用a和dbbca匹配到第2位’。但考虑到这样是跳过了一些字母的,会导致最终表末结果不到10,那么也就不用担心会造成错误结果了)。

代码实现

class Solution {
   
public:
	bool isInterleave(string s1, string s2, string s3) {
   
		if (s1.size() + s2.size() != s3.size()) {
   
			return false;
		}
		vector<vector<int>> dp_map(s1.size<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值