題目來源:力扣(LeetCode)https://leetcode-cn.com/problems/interleaving-stringpython
給定三個字符串 s1, s2, s3, 驗證 s3 是不是由 s1 和 s2 交錯組成的。bash
示例 1:spa
輸入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" 輸出: true
示例 2:.net
輸入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" 輸出: false
思路:動態規劃code
在這裏,咱們使用 不一樣路徑 這道題的思想去解決問題,向下向右去移動,求得是否存在這樣的路徑。blog
那麼這個問題就能夠轉換爲求證,s3 是否可以從向下選取 s1,向右選取 s2,這樣的形式,去求得是否存在 s3 這條路徑。leetcode
設 dp[i][j]
表示 s1 前 i 個字符和 s2 前 j 個字符可以拼接成 s3(i+j) 個字符,也就是當前路徑存在。rem
若是 s1 的第 i 個元素和 s3 的第 i+j 個元素相等,那麼 dp[i][j]
是否成立,則須要看 dp[i-1][j]
是否成立,也就是這裏須要看 s1 的前 i-1 個元素和 s2 的前 j 個元素可否拼接成 s3 的前 i+j-1 個元素。字符串
一樣的 若是 s2 的第 j 個元素和 s3 的第 i+j 個元素相等,此時 dp[i][j]
是否成立,則須要看 dp[i][j-1]
是否成立,也就是須要看 s2 的前 i 個元素和 s2 的前 j-1 個元素是否可以拼接成 s3 的前 i+j-1 個元素。get
那麼最終的狀態轉移方程爲:
dp[i][j] = (dp[i-1][j] and s3[i+j-1]=s1[i-1]) or (dp[i][j-1] and s3[i+j-1]=s2[j-1])
具體的實現代碼以下。
class Solution: def isInterleave(self, s1: str, s2: str, s3: str) -> bool: # 先處理特殊狀況,若是 s1 和 s2 的長度和不等於 s3 的長度,則返回 False。由於沒法交錯拼接 if len(s1) + len(s2) != len(s3): return False m = len(s1) n = len(s2) # 狀態定義 dp = [[False] * (n+1) for _ in range(m+1)] # 初始化 dp[0][0] = True for i in range(1, m+1): dp[i][0] = dp[i-1][0] and s3[i-1] == s1[i-1] for j in range(1, n+1): dp[0][j] = dp[0][j-1] and s3[j-1] == s2[j-1] for i in range(1, m+1): for j in range(1, n+1): dp[i][j] = (dp[i-1][j] and s3[i+j-1]==s1[i-1]) or (dp[i][j-1] and s3[i+j-1]==s2[j-1]) return dp[-1][-1]
公衆號 【書所集錄】