动态规划:
dp[ i ][ j ]表示在s3的前i+j个元素,也就是说这些元素是从s1拿出 i 个元素,从s2拿出 j 个元素组成s3的前i+j个元素。dp[ i ][ j ]表示现在s3的i+j个元素是不是交错的。
动态方程的意思是:判断 i+j 个元素是不是交错的,可以通过判断前 i+j-1个是不是交错的来决定i+j 是不是交错的。假如s3第i+j 个元素是从s1(s1的第 i 个元素 --> s1[ i -1])来的,也就是 s3[i + j - 1] == s1[i - 1]的情况下,如果拿出去s1[i - 1]之后 前面i+j-1个元素是交错的,加上了s1[i - 1] s3也是交错的。判断是从s2来的也一样。
i = 0 或者 j = 0时,要单独设置一下。就是从头开始看是不是重合。
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
n1 = len(s1)
n2 = len(s2)
n3 = len(s3)
if n1 + n2 != n3: return False
dp = [[False] * (n2 + 1) for _ in range(n1 + 1)]
dp[0][0] = True
# 第一行
for j in range(1, n2 + 1):
dp[0][j] = (dp[0][j - 1] and s2[j - 1] == s3[j - 1])
# 第一列
for i in range(1, n1 + 1):
dp[i][0] = (dp[i - 1][0] and s1[i - 1] == s3[i - 1])
# print(dp)
for i in range(1, n1 + 1):
for j in range(1, n2 + 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])
# print(dp)
return dp[-1][-1]
递归:
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
import functools
n1 = len(s1)
n2 = len(s2)
n3 = len(s3)
@functools.lru_cache(None) # 递归常用的装饰器,提高性能,节省时间。
def helper(i, j, k):
if i == n1 and j == n2 and k == n3:
return True
if k < n3:
# 把s3的数按位和s1,s2的比较。
if i < n1 and s1[i] == s3[k] and helper(i+1, j, k+1):
return True
if j < n2 and s2[j] == s3[k] and helper(i, j+1, k+1):
return True
return False
return helper(0,0,0)