LeetCode(力扣) 97题:交错字符串----动态规划求解附带详细注释

题目描述:
给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。
两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:

  1. s = s1 + s2 + … + sn
  2. t = t1 + t2 + … + tm
  3. |n - m| <= 1
  4. 交错 是 s1 + t1 + s2 + t2 + s3 + t3 + … 或者 t1 + s1 + t2 + s2 + t3 + s3 + …

示例:
LeetCode(力扣) 97题:交错字符串----动态规划求解附带详细注释_第1张图片

输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出:true

思路:

看到这道题,说实话我第一想法是暴力求解,没有想到用动态规划,献丑了。下边就说一说动态规划的思路吧。因为有两个字符串 s1 和 s2,这里动态规划需要用到二维数组。定义dp[][]数组,其中dp[i][j]表示 s1 的前 i 个元素和 s2 的前 j 个元素能否交错组成s3[i + j]。关于动态转移方程:

dp[i][j] = (dp[i - 1][j] and s1[i - 1] == s3[i + j - 1]) or (dp[i][j - 1] and s2[j - 1] == s3[i + j - 1])

意思就是符合以下两种条件之一,dp[i][j]便为True
条件1:

dp[i - 1][j] and s1[i - 1] == s3[i + j - 1]

s1 的前 i - 1 个元素和 s2 的前 j 个元素可以交错组合成 s3[0 : i + j - 1],并且 s1 的第 i 个元素等于 s3 的第 i + j - 1 个元素。

dp[i][j - 1] and s2[j - 1] == s3[i + j - 1]

s1 的前 i - 1 个元素和 s2 的前 j 个元素可以交错组合成 s3[0 : i + j - 1],并且 s2 的第 j 个元素等于 s3 的第 i + j - 1 个元素。

明确了dp数组的含义和动态转移方程之后,接下来确定初始条件dp[0][0], 表示s1 的前 0 个元素和 s2 的前 0 个元素可以交错组合成 ‘ ’,这当然是True。接下来需要注意的是,我们先单独对 s1 和 s2 判断,确定 dp 数组的第一行和第一列,拿 dp 数组的第一行 dp[0][j] 来举例, 表示 s2 的前 j - 1 个元素可以交错组成 s3[0 : j]。

初始条件确立之后,我们来看一下完整代码吧。

代码:

class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
        # 如果都为空,则可以交错组成
        if s1 == "" and s2 == "" and s3 == "":
            return True
        # 根据长度判断,如果长度不等,那么不能交错组成
        len1, len2, len3 = len(s1), len(s2), len(s3)

        if len1 + len2 != len3:
            return False
        # 定义DP数组
        dp = [[False] * (len2 + 1) for i in range(len1 + 1)]
        # 确定初始条件
        dp[0][0] = True

        for i in range(1, len1 + 1):
            dp[i][0] = (dp[i - 1][0] and s3[i - 1] == s1[i - 1])
        
        for j in range(1, len2 + 1):
            dp[0][j] = (dp[0][j - 1] and s3[j - 1] == s2[j - 1])
        # 根据转移方程确定接下来的元素
        for i in range(1, len1 + 1):
            for j in range(1, len2 + 1):
                dp[i][j] = (dp[i - 1][j] and s1[i - 1] == s3[i + j - 1]) or (dp[i][j - 1] and s2[j - 1] == s3[i + j - 1])
        # 返回DP数组的最后一个元素,即s1和s2能不能交错组成s3
        return dp[-1][-1]

运行结果:

LeetCode(力扣) 97题:交错字符串----动态规划求解附带详细注释_第2张图片

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