问题:给定三个字符串A,B,X,判断X是否是由A,B的字符交错而形成(True/False)
例:A = ['a','a','b','c','c'],B = ['d','b','b','a','c']
X = ["a","a",'d',"b",'b',"c",'b',"c",'a','c']
输出:True(双引号是A中的字符,单引号是B中的字符)
问题分析:令m = len(A),n = len(B),x = len(X),若x != m+n,则X肯定不能由A、B交错形成。
否则,考虑最后一步,X由A、B交错形成,X的最后一个字符(X[m+n-1]),
case1:是A[m-1],则X[0,...,m+n-2]由A[0,...,m-2]和B[0,...n-1]交错形成
case2:是B[n-1],则X[0,...,m+n-2]由A[0,...,m-1]和B[0,...n-2]交错形成
子问题:本来要求X[0,...,m+n-1]是否由A[0,...,m-1]和B[0,...n-1]交错形成
现在要求则X[0,...,m+n-2]是否由A[0,...,m-2]和B[0,...n-1]交错形成;
X[0,...,m+n-2]是否由A[0,...,m-1]和B[0,...n-2]交错形成。
转移方程:设f[i][j]表示X的前i+j个字符X[0,...,i+j-1]是否
由A的前i个字符A[0,...,i-1]和B的前j个字符B[0,...,j-1]个字符交错而成
则f[i][j] = (f[i-1][j] | X[i+j-1] = A[i-1]) OR (f[i][j-1] | X[i+j-1] = B[j-1])
case1 OR case2
初始情况:
f[0][0] = True,空字符可以由空字符形成。
边界情况:
i = 0,则只考虑case2,
j = 0,则只考虑case1
计算顺序:
f[0][0]...f[0][n]
.
.
.
f[m][0]...f[m][n]
答案:f[m][n]
时间复杂度O(mn),空间复杂度O(mn),可以优化到O(n)
代码及注释如下:
def interleaving_str(A,B,X):
m , n = len(A) , len(B)
if len(X) != m+n:
return False
f = [[False for i in range(n+1)] for j in range(m+1)]
for i in range(m+1):
for j in range(n+1):
#初始情况,f[0][0] = False,其实没必要,创建的时候就已经设好了
if i == 0 and j == 0:
f[i][j] = True
continue
f[i][j] = False
#case1:f[i-1][j] | X[i+j-1] = A[i-1]
if i > 0 and X[i+j-1] == A[i-1]:
f[i][j] = f[i][j] or f[i-1][j]
#case2:f[i][j-1] | X[i+j-1] = B[j-1]
if j > 0 and X[i+j-1] == B[j-1]:
f[i][j] = f[i][j] or f[i][j-1]
return f[m][n]
A = ['a','a','b','c','c']
B = ['d','b','b','a','c']
X = ["a","a",'d',"b",'b',"c",'b',"c",'a','c']
print(interleaving_str(A,B,X))
#结果:True
未完待续。。。空间优化,和之前类似old new数组。