【DP】交错字符串
https://leetcode.cn/problems/interleaving-string/description/?envType=study-plan-v2&envId=top-interview-150
以下是通过动态规划解决该问题的正确方法。首先,如果字符串 s1 和 s2 的长度之和不等于字符串 s3 的长度,即 |s1| + |s2| ≠ |s3|,那么字符串 s3 不可能由字符串 s1 和 s2 交错组成。当 |s1| + |s2| = |s3| 时,我们可以使用动态规划来求解。
我们定义 f(i, j) 表示字符串 s1 的前 i 个元素和字符串 s2 的前 j 个元素是否能交错组成字符串 s3 的前 i+j 个元素。如果字符串 s1 的第 i 个元素和字符串 s3 的第 i+j 个元素相等,那么字符串 s1 的前 i 个元素和字符串 s2 的前 j 个元素是否能交错组成字符串 s3 的前 i+j 个元素取决于字符串 s1 的前 i-1 个元素和字符串 s2 的前 j 个元素是否能交错组成字符串 s3 的前 i+j-1 个元素,即此时 f(i, j) 取决于 f(i-1, j)。在这种情况下,如果 f(i-1, j) 为真,则 f(i, j) 也为真。同样地,如果字符串 s2 的第 j 个元素和字符串 s3 的第 i+j 个元素相等,并且 f(i, j-1) 为真,则 f(i, j) 也为真。因此,我们可以得出以下动态规划转移方程:
f(i, j) = [f(i-1, j) and s1(i-1) = s3(p)] or [f(i, j-1) and s2(j-1) = s3(p)]
其中,p = i + j - 1。
这种动态规划的思路可以帮助我们判断字符串 s3 是否可以由字符串 s1 和 s2 交错组成。
注意: 这道题不能用双指针,双指针只能用于连续字符串,不能用于交错字符串
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
m, n = len(s1), len(s2)
if m + n != len(s3):
return False
dp = [[False] * (n + 1) for _ in range(m + 1)]
dp[0][0] = True
for i in range(1, m + 1):
dp[i][0] = dp[i - 1][0] and s1[i - 1] == s3[i - 1]
for j in range(1, n + 1):
dp[0][j] = dp[0][j - 1] and s2[j - 1] == s3[j - 1]
for i in range(1, m + 1):
for j in range(1, n + 1):
dp[i][j] = dp[i - 1][j] and (s1[i - 1] == s3[i + j - 1] or s2[j - 1] == s3[i + j - 1])
return dp[m][n]