97.Interleaving String === ###### tags: `Medium` `String` `DP` [97. Interleaving String](https://leetcode.com/problems/interleaving-string/) ### 題目描述 Given strings `s1`, `s2`, and `s3`, find whether `s3` is formed by an **interleaving** of `s1` and `s2`. An **interleaving** of two strings `s` and `t` is a configuration where `s` and `t` are divided into `n` and `m` substrings respectively, such that: * `s = s1 + s2 + ... + sn` * `t = t1 + t2 + ... + tm` * `|n - m| <= 1` * The **interleaving** is `s1 + t1 + s2 + t2 + s3 + t3 + ...` or `t1 + s1 + t2 + s2 + t3 + s3 + ...` **Note:** `a + b` is the concatenation of strings `a` and `b`. ### 範例 **Example 1:** ![](https://assets.leetcode.com/uploads/2020/09/02/interleave.jpg) ``` Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" Output: true Explanation: One way to obtain s3 is: Split s1 into s1 = "aa" + "bc" + "c", and s2 into s2 = "dbbc" + "a". Interleaving the two splits, we get "aa" + "dbbc" + "bc" + "a" + "c" = "aadbbcbcac". Since s3 can be obtained by interleaving s1 and s2, we return true. ``` **Example 2:** ``` Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" Output: false Explanation: Notice how it is impossible to interleave s2 with any other string to obtain s3. ``` **Example 3:** ``` Input: s1 = "", s2 = "", s3 = "" Output: true ``` **Constraints**: * 0 <= `s1.length`, `s2.length` <= 100 * 0 <= `s3.length` <= 200 * `s1`, `s2`, and `s3` consist of lowercase English letters. **Follow up:** Could you solve it using only `O(s2.length)` additional memory space? ### 解答 #### TypeScript `dp[i][j]` 表示 `s1` 的前 `i` 個字元和 `s2` 的前 `j` 個字元是否可以交錯組合成 `s3` 的前 `i + j` 個字元。 從下面兩個方向達到目前狀態 `(i,j)`: 1. 從 `(i - 1, j)` 轉移: - 如果 `dp[i - 1][j] == true`,代表著 `s1` 的前 `i - 1` 個字元和 `s2` 的前 `j` 個字元可以交錯組合成 `s3` 的前 `i + j - 1` 個字元。 - 然後我們只需檢查 `s1[i - 1]` 是否等於 `s3[i + j - 1]`。如果相等,則 `dp[i][j]` 也為 `true` 2. 從 `i, j - 1` 轉移: - 如果 `dp[i, j - 1] == true`,代表著 `s1` 的前 `i` 個字元和 `s2` 的前 `j - 1` 個字元可以交錯組合成 `s3` 的前 `i + j - 1` 個字元。 - 一樣檢查 `s2[j - 1]` 是否等於 `s3[i + j - 1]`。如果相等,則 `dp[i][j]` 也為 `true` ```typescript function isInterleave(s1: string, s2: string, s3: string): boolean { if (s1.length + s2.length !== s3.length) return false; const dp: boolean[][] = new Array(s1.length + 1) .fill(0) .map(() => new Array(s2.length + 1).fill(false)); dp[0][0] = true; // s2 = '' for (let i = 1; i <= s1.length; i++) { dp[i][0] = dp[i - 1][0] && s1[i - 1] === s3[i - 1]; } // s1 = '' for (let j = 1; j <= s2.length; j++) { dp[0][j] = dp[0][j - 1] && s2[j - 1] === s3[j - 1]; } for (let i = 1; i <= s1.length; i++) { for (let j = 1; j <= s2.length; j++) { dp[i][j] = (dp[i - 1][j] && s1[i - 1] === s3[i + j - 1]) || (dp[i][j - 1] && s2[j - 1] === s3[i + j - 1]); } } return dp[s1.length][s2.length]; } ``` > [name=sheep][time=Fri, 25 Aug 2023] #### Python ```python= class Solution: def isInterleave(self, s1: str, s2: str, s3: str) -> bool: if len(s1) + len(s2) != len(s3): return False @cache def dfs(i, j): if i == 0 and j == 0: return True if i == 0: return s2[j - 1] == s3[j - 1] and dfs(i, j - 1) if j == 0: return s1[i - 1] == s3[i - 1] and dfs(i - 1, j) return (s1[i - 1] == s3[i + j - 1] and dfs(i - 1, j)) \ or (s2[j - 1] == s3[i + j - 1] and dfs(i, j - 1)) return dfs(len(s1), len(s2)) ``` > [name=Yen-Chi Chen][time=Fri, Aug 25, 2023] ### Reference [回到題目列表](https://marsgoat.github.io/XNnote/coding/leetcodeEveryDay.html)