「前端刷题」97. 交错字符串

114 阅读1分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

题目

链接:leetcode-cn.com/problems/in…

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

两个字符串 st 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:

  • 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 意味着字符串 ab 连接。

示例 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
  • s1s2、和 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]
};