# Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.## For example,# Given:# s1 = "aabcc",# s2 = "dbbca",## When s3 = "aadbbcbcac", return true.# When s3 = "aadbbbaccc", return false.
AC
classSolution():defisInterleave(self, s1, s2, s3):
r, c, l= len(s1), len(s2), len(s3)
if r+c != l:
returnFalse
stack, visited = [(0, 0)], set((0, 0))
while stack:
x, y = stack.pop()
if x+y == l:
returnTrueif x+1 <= r and s1[x] == s3[x+y] and (x+1, y) notin visited:
stack.append((x+1, y)); visited.add((x+1, y))
if y+1 <= c and s2[y] == s3[x+y] and (x, y+1) notin visited:
stack.append((x, y+1)); visited.add((x, y+1))
returnFalse# Time: O(m * n)# Space: O(m + n)# Dynamic Programming + Sliding WindowclassSolution2():defisInterleave(self, s1, s2, s3):if len(s1) + len(s2) != len(s3):
returnFalseif len(s1) > len(s2):
return self.isInterleave(s2, s1, s3)
match = [Falsefor i in range(len(s1) + 1)]
match[0] = Truefor i in range(1, len(s1) + 1):
match[i] = match[i -1] and s1[i - 1] == s3[i - 1]
for j in range(1, len(s2) + 1):
match[0] = match[0] and s2[j - 1] == s3[j - 1]
for i in range(1, len(s1) + 1):
match[i] = (match[i - 1] and s1[i - 1] == s3[i + j - 1]) \
or (match[i] and s2[j - 1] == s3[i + j - 1])
return match[-1]
# Time: O(m * n)# Space: O(m * n)# Dynamic ProgrammingclassSolution3():defisInterleave(self, s1, s2, s3):if len(s1) + len(s2) != len(s3):
returnFalse
match = [[Falsefor i in range(len(s2) + 1)] for j in range(len(s1) + 1)]
match[0][0] = Truefor i in range(1, len(s1) + 1):
match[i][0] = match[i - 1][0] and s1[i - 1] == s3[i - 1]
for j in range(1, len(s2) + 1):
match[0][j] = match[0][j - 1] and s2[j - 1] == s3[j - 1]
for i in range(1, len(s1) + 1):
for j in range(1, len(s2) + 1):
match[i][j] = (match[i - 1][j] and s1[i - 1] == s3[i + j - 1]) \
or (match[i][j - 1] and s2[j - 1] == s3[i + j - 1])
return match[-1][-1]
# Time: O(m * n)# Space: O(m * n)# Recursive + HashclassSolution4():defisInterleave(self, s1, s2, s3):
self.match = {}
if len(s1) + len(s2) != len(s3):
returnFalsereturn self.isInterleaveRecu(s1, s2, s3, 0, 0, 0)
defisInterleaveRecu(self, s1, s2, s3, a, b, c):if repr([a, b]) in self.match.keys():
return self.match[repr([a, b])]
if c == len(s3):
returnTrue
result = Falseif a < len(s1) and s1[a] == s3[c]:
result = result or self.isInterleaveRecu(s1, s2, s3, a + 1, b, c + 1)
if b < len(s2) and s2[b] == s3[c]:
result = result or self.isInterleaveRecu(s1, s2, s3, a, b + 1, c + 1)
self.match[repr([a, b])] = result
return result
if __name__ == "__main__":
assert Solution().isInterleave("a", "", "a") == Trueassert Solution().isInterleave("aabcc", "dbbca", "aadbbcbcac") == Trueassert Solution().isInterleave("aabcc", "dbbca", "aadbbbaccc") == False