Given stringsĀ s1,Ā s2, andĀ s3, find whetherĀ s3Ā is formed by anĀ interleavingĀ ofĀ s1Ā andĀ s2.
AnĀ interleavingĀ of two stringsĀ sĀ andĀ tĀ is a configuration whereĀ sĀ andĀ tĀ are divided intoĀ nĀ andĀ mĀ substrings respectively, such that:
s = s1 + s2 + ... + snt = t1 + t2 + ... + tm|n - m| <= 1- TheĀ interleavingĀ isĀ
s1 + t1 + s2 + t2 + s3 + t3 + ...Ā orĀt1 + s1 + t2 + s2 + t3 + s3 + ...
Note:Ā a + bĀ is the concatenation of stringsĀ aĀ andĀ b.
solution
recursion w/ memoization
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
if len(s1) + len(s2) != len(s3):
return False
memo = {}
def recurse(idx1, idx2):
if idx1 == len(s1) and idx2 == len(s2):
return True
if (idx1, idx2) in memo:
return memo[(idx1, idx2)]
ret = False
if idx1 < len(s1) and s1[idx1] == s3[idx1+idx2]:
ret = ret or recurse(idx1+1, idx2)
if idx2 < len(s2) and s2[idx2] == s3[idx1+idx2]:
ret = ret or recurse(idx1, idx2+1)
memo[(idx1, idx2)] = ret
return memo[(idx1, idx2)]
return recurse(0, 0)2d dynamic programming
This is a similar idea to recursion, but we build bottom-up. dp[i][j] represents whether we can build the first i+j letters in s3 using the first i letters of s2 and the first j letters of s1. (Thereās an off-by-one calculation that needs to be done because we need to store base case rows/columns in the array that represent situations when we havenāt yet used any of either/both string(s)).
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
if len(s1) + len(s2) != len(s3):
return False
dp = [[0 for j in range(len(s1)+1)] for i in range(len(s2)+1)]
for i in range(len(dp)):
for j in range(len(dp[0])):
if i == 0 and j == 0:
dp[i][j] = True
elif i == 0:
dp[i][j] = s1[j-1] == s3[j-1] and dp[i][j-1]
elif j == 0:
dp[i][j] = s2[i-1] == s3[i-1] and dp[i-1][j]
else:
ret = False
# we previously used all of the first j chars of s1,
# so now we have to use i'th char of s2
# to match the next char in s3
if dp[i-1][j]:
ret = ret or s2[i-1] == s3[i+j-1]
# we previously used all of the first i chars of s2,
# so now we have to use the j'th char of s1
# to match the next char in s3
if dp[i][j-1]:
ret = ret or s1[j-1] == s3[i+j-1]
dp[i][j] = ret
return dp[-1][-1]