1. 程式人生 > 實用技巧 >LeetCode 97. 交錯字串 | Python

LeetCode 97. 交錯字串 | Python

97. 交錯字串


題目來源:力扣(LeetCode)https://leetcode-cn.com/problems/interleaving-string

題目


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

示例 1:

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

示例 2:

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

解題思路


思路:動態規劃

在這裡,我們使用 不同路徑 這道題的思想去解決問題,向下向右去移動,求得是否存在這樣的路徑。

那麼這個問題就可以轉換為求證,s3 是否能夠從向下選取 s1,向右選取 s2,這樣的形式,去求得是否存在 s3 這條路徑。

狀態定義

dp[i][j] 表示 s1 前 i 個字元和 s2 前 j 個字元能夠拼接成 s3(i+j) 個字元,也就是當前路徑存在。

狀態轉移方程

如果 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 個元素。

那麼最終的狀態轉移方程為:

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])

狀態初始化

  • dp[0][0] = True
  • 如果 j = 0, dp[i][0] 是否成立,取決於 dp[i-1][0] 以及 s1 的第 i 個字元是否等於 s3 的第 i 個字元;
  • 如果 i = 0, dp[0][j] 是否成立,取決於 dp[0][j-1] 以及 s3 的第 i 個字元與 s2 的第 i 個字元是否相等。

具體的實現程式碼如下。

程式碼實現


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]

實現結果


歡迎關注


公眾號 【書所集錄