「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。
题目
链接:leetcode-cn.com/problems/in…
给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。
两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:
s = s1 + s2 + ... + snt = 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 <= 1000 <= s3.length <= 200s1、s2、和s3都由小写英文字母组成
思路
现有s1 和s2 两个字符串,s1取一部分 s2取一份相互交叉形成新字符串 s3。所以s1长度 加上 s2长度和一定是s3长度和。交错时s1和s2自己本身的顺序不能变。两个字符串合并,一定是二维数组,dp[i][j]。js实现二维数组使用 Array.from 第二个参数。当然也可以其他方式实现。 定义dp[i][j]是 s1前i个字符 和s2前j个字符是否和s3前i+j个字符匹配。记住,这里定义的前几个字符,那么当前对应的值就是 s1[i-1] 和s2[j-1]。前一项,那么索引就是0麽,大家应该能理解。s1和s2对应在s3中的前后位置不定,所以有两种情况。即
dp[i][j] = s1匹配 dp[i-1][j]匹配, 同时 当前项相等s1[i-1] == s3[i+j-1]
s2匹配 dp[i][j-1]匹配,同时 当前项相同s2[j-1] == s3[i+j-1]
var isInterleave = function(s1, s2, s3) {
let n1= s1.length
let n2 = s2.length
if (n1+n2!=s3.length) return false
let dp = Array.from(new Array(n1+1), () => new Array(n2+1))
dp[0][0] = true
// 初始化
for(let i=1;i<=n1;i++) {
dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1]
}
for(let i=1;i<=n2;i++) {
dp[0][i] = dp[0][i-1] && s2[i-1] == s3[i-1]
}
for(let i =1;i<=n1;i++) {
for(let j=1;j<=n2;j++) {
dp[i][j] = dp[i-1][j] && s1[i-1] == s3[i-1+j] || dp[i][j-1] && s2[j-1] ==s3[i+j-1]
}
}
// s1的前i项,当前项就是 s1[i-1]
return dp[n1][n2]
};