给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
示例 1:
输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出: true
示例 2:
输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出: false
先检查s3的第一个字符,如果等于s1的第一个字符,且不等于s2的第二个字符,将s1和s3向后移动一位,递归。当等于s2的第一个字符且不等于与s1的第一个字符的时候,将s2和s3向后移动一位,递归。如果即等于s1的第一个字符又等于s2的第一个字符,就有可能有两种情况,s2不动,s1向后移动一位或者是s1不动,s2向后移动一位。
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
if len(s3) != len(s1) + len(s2):
return False
if s1 == "" and s2 == "" and s3 == "":
return True
if s1 == "":
return s2 == s3
if s2 == "":
return s1 == s3
if s3[0] == s1[0] and s3[0] != s2[0]:
return self.isInterleave(s1[1:],s2,s3[1:])
elif s3[0] == s2[0] and s3[0] != s1[0]:
return self.isInterleave(s1,s2[1:],s3[1:])
elif s3[0] == s2[0] and s3[0] == s1[0]:
return self.isInterleave(s1[1:],s2,s3[1:]) or self.isInterleave(s1,s2[1:],s3[1:])
else:
return False
dp[i][j] 表示用 s1的前 (i+1)和 s2 的前 (j+1) 个字符,总共 (i+j+2)个字符,是否交错构成 s3的前缀。为了求出 dp[i][j],我们需要考虑 2 种情况:
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
if len(s3) != len(s1) + len(s2):
return False
dp = [[True for j in range(len(s1)+1)] for i in range(len(s2)+1)]
for i in range(len(s2)+1):
for j in range(len(s1)+1):
if i == 0 and j == 0:
dp[i][j] = True
elif i == 0:
dp[i][j] = dp[i][j-1] and s1[j-1] == s3[j-1]
elif j == 0:
dp[i][j] = dp[i-1][j] and s2[i-1] == s3[i-1]
else:
dp[i][j] = (dp[i-1][j] and s2[i-1] == s3[i+j-1]) or (dp[i][j-1] and s1[j-1] == s3[i+j-1])
return dp[-1][-1]
和其他的动态规划一样,仍然可以用一个一位数组来优化二维数组。
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
if len(s3) != len(s1) + len(s2):
return False
dp = [True for i in range(len(s1)+1)]
for i in range(1,len(s1)+1):
dp[i] = dp[i-1] and s1[i-1] == s3[i-1]
for i in range(len(s2)):
for j in range(len(s1)+1):
if j == 0:
dp[j] = dp[j] and s2[i] == s3[i]
else:
dp[j] = (dp[j-1] and s1[j-1] == s3[i+j]) or (dp[j] and s2[i] == s3[i+j])
return dp[-1]