1. 程式人生 > >演算法57----字串的交錯組成【動態規劃】

演算法57----字串的交錯組成【動態規劃】

一、題目:交錯字串

給定三個字串 s1, s2, s3, 驗證 s3 是否是由 s1 和 s2 交錯組成的。

示例 1:

輸入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
輸出: true

示例 2:

輸入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
輸出: false

二、思路:動態規劃:時間O(M*N ),空間O(M*N)

構造一個(M+1)*(N+1)的矩陣dp:dp[i][j] 代表是s1的前i個字元與s3中匹配,s2中前j個字元與s3中匹配.

  • 初始化:首行首列則是假設其中一個字串為空時,另一個字串是否與目標字串一一對應。
  1. dp[0][0]=true.   # s3為空時可以由str1和str2的空字串組成
  2. dp[i][0]:表示s3[0...i-1]能否由str1[0.....i-1]組成,若可以則dp[i][0]=true,反之則為false
    • dp[i][0] = dp[i-1][0] and s1[i-1][0] == s3[i-1][0]
  3. dp[0][j]:表示s3[0...j-1]能否由str2[0.....j-1]組成,若可以則dp[0][j]=true,反之則為false
    • dp[0][j] = dp[0][j-1] and s2[j-1] == s3[j-1]
  • 狀態方程:其他位置(i,j),dp[i][j]的值:

dp[i][j] = (dp[i-1][j] == True and s1[i-1] == s3[i+j-1]) or (dp[i][j-1] ==True and s2[j-1] == s3[i+j-1])

  • dp[i-1][j]:代表s3[i+j-2]能否被str1[0...i-2]和str2[0...j-1]交錯組成,若可以,以及str1[i-1]等於s3[i+j-1],則dp[i][j]=true,反之則為false
  • dp[i][j-1]:代表s3[i+j-2]能否被str1[0...i-1]和str2[0...j-2]交錯組成,若可以,以及str2[j-1]等於s3[i+j-1],則dp[i][j]=true,反之則為false
  • 若前兩種情況都不滿足,則dp[i][j]=false

三、程式碼:

def isInterleave(s1, s2, s3):
    if len(s3) != len(s2) + len(s1):
        return False
    dp = [[False] * (len(s2)+1) for i in range(len(s1)+1)]
#初始化 dp[0][0]
= True for j in range(1,len(s2)+1): dp[0][j] = dp[0][j-1] and s2[j-1] == s3[j-1] for i in range(1,len(s1)+1): dp[i][0] = dp[i-1][0] and s1[i-1][0] == s3[i-1][0]
#狀態方程
for i in range(1,len(s1)): for j in range(1,len(s2)): dp[i][j] = (dp[i-1][j] == True and s1[i-1] == s3[i+j-1]) or (dp[i][j-1] ==True and s2[j-1] == s3[i+j-1]) return dp[-1][-1] s1 = "aabcc" s2 = "dbbca" s3 = "aadbbcbcac" isInterleave(s1, s2, s3)