给出三个字符串:s1、s2、s3,判断s3是否由s1和s2交叉构成。
样例 比如 s1 = “aabcc” s2 = “dbbca”
- 当 s3 = "aadbbcbcac",返回 true. - 当 s3 = "aadbbbaccc", 返回 false.动态规划 dp[i,j]表示s1的前i个字符与s2的前j个字符能否交叉构成s3的前(i+j)个字符。 对于s3中的第i+j个字符,有以下几种可能:
s3[i+j]==s1[i] and s3[i+j]==s2[j]s3[i+j]==s1[i] and s3[i+j]!=s2[j]s3[i+j]!=s1[i] and s3[i+j]==s2[j]s3[i+j]!=s1[i] and s3[i+j]!=s2[j]第1种,若s1的前i-1个字符与s2的前j个字符能交叉构成s3的前i-1+j个字符,即dp[i-1,j]==True,那么dp[i,j]=True。或者,s2的前j-1个字符和s1的前i个字符能交叉构成s3的前i+j-1个字符,即dp[i,j-1]==True,那么dp[i,j]=True。综上,dp[i,j]=dp[i-1,j] or dp[i,j-1]。
第2种,若s1的前i-1个字符与s2的前j个字符能交叉构成s3的前i-1+j个字符,即dp[i-1,j]==True,那么dp[i,j]=True。 但是,由于s3[i+j]!=s2[j],所以无论s2的前j-1个字符和s1的前i个字符能否交叉构成s3的前i+j-1个字符,即无论dp[i,j-1]是否为True,dp[i,j]都是False。综上,dp[i,j]=dp[i-1,j]。
第3种与第2种类似。
第4种,dp[i,j]一定为False。
代码如下:
class Solution: """ @param: : A string @param: : A string @param: : A string @return: Determine whether s3 is formed by interleaving of s1 and s2 """ def isInterleave(self, s1, s2, s3): # write your code here、 m=len(s1) n=len(s2) z=len(s3) if m+n!=z: #当长度不匹配时,返回False return False dp=[[0 for x in range(n+1)] for y in range(m+1)] dp[0][0]=True #s1前0个与s2前0个能交叉构成s3前0个 for i in range(1,m+1): #s1前i个与s2前0个能否构成s3前i个 if s1[i-1]==s3[i-1]: dp[i][0]=dp[i-1][0] else: dp[i][0]=False for j in range(1,n+1): #s1前0个与s2前j个能否构成s3前j个 if s2[j-1]==s3[j-1]: dp[0][j]=dp[0][j-1] else: dp[0][j]=False for i in range(1,m+1): #s1前i个与s2前j个能否构成s3前i+j个(i>=1,j>=1) for j in range(1,n+1): if s1[i-1]==s3[i+j-1] and s2[j-1]==s3[i+j-1]: dp[i][j]=(dp[i-1][j] or dp[i][j-1]) elif s1[i-1]==s3[i+j-1]: dp[i][j]=dp[i-1][j] elif s2[j-1]==s3[i+j-1]: dp[i][j]=dp[i][j-1] else: dp[i][j]=False return dp[m][n]