leetcode (力扣) 97. 交错字符串(动态规划)

文章目录

  • 题目描述
  • 思路分析
  • 完整代码

题目描述

给定三个字符串 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:
leetcode (力扣) 97. 交错字符串(动态规划)_第1张图片
输入:s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac”
输出:true

思路分析

动规题。

1.确定dp数组含义:
dp[i][j] 表示s1前i个字符和s2前j个字符能否构成s3的前i+j个字符。

2.分析递推公式:

由于需要s1+s2来构成s3,所以设想子问题s3的最后一个字符是由谁构成的。

  • 若s3的最后一个字符由s1提供,则有:s3[i+j] = s1[i],而 s3 此前的 i+j−1个字符,可由 s1 的前 i−1 字符和 s2 的前 j 个字符共同提供。这时候就要去判断dp数组的上一个状态了,即若 dp[i−1][j]为真,则 dp[i][j]为真。
  • 若s3最后一个字符由s2提供,则同理
     if s1[i-1] == s3[i+j-1] and dp[i-1][j]:
         dp[i][j] = True
     if s2[j-1] == s3[i+j-1] and dp[i][j-1]:
         dp[i][j] = True

别忘了 dp[i][j] 表示s1前i个字符(不包含i)

3.初始化

由于为了方便,所以数组都从下标1开始。
在初始化的时候 多开一行一列的dp数组。

必有:dp [0][0] = True。

dp的第二行和第二列也需要初始化,就直接比较当前s1或者s2字符和当前的s3字符是否相等,如果相等,看看前一个dp位置是否也是True,如果是则当前dp位置也是True。

for i in range(1, n + 1):
    dp [i][0] = dp [i - 1][0] and s1[i - 1] == s3[i - 1]
for i in range(1, m + 1):
    dp [0][i] = dp [0][i - 1] and s2[i - 1] == s3[i - 1]

完整代码

class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
        # dp[i][j] 表示s1前i个字符和s2前j个字符能否构成s3的前i+j个字符

        n, m, l = len(s1), len(s2), len(s3)
        if n + m != l:
            return False
        dp = [[False] * (m + 1) for _ in range(n + 1)]
        dp [0][0] = True
        for i in range(1, n + 1):
            dp [i][0] = dp [i - 1][0] and s1[i - 1] == s3[i - 1]
        for i in range(1, m + 1):
            dp [0][i] = dp [0][i - 1] and s2[i - 1] == s3[i - 1]

        for i in range(1,n+1):
            for j in range(1,m+1):
                if s1[i-1] == s3[i+j-1] and dp[i-1][j]:
                    dp[i][j] = True
                if s2[j-1] == s3[i+j-1] and dp[i][j-1]:
                    dp[i][j] = True
        return dp[-1][-1]```

你可能感兴趣的:(leetcode,动态规划,算法)