題目描述:給定三個字串 s1、s2、s3,判斷 s3 是否可以由 s1 和 s2 交錯(interleaving)而成。交錯的意思是:將 s1 和 s2 的字元依原本順序分拆後重新合併,且每個字元都只使用一次。
解題思路:
二維動態規劃:
定義 dp[i][j] 為:s1 的前 i 個字元與 s2 的前 j 個字元,能否交錯組成 s3 的前 i+j 個字元。
初始化:
dp[0][0] = true(空字串交錯仍為空字串)dp[i][0]:僅用 s1 前 i 個字元,等於 s1[0..i-1] == s3[0..i-1]dp[0][j]:僅用 s2 前 j 個字元,等於 s2[0..j-1] == s3[0..j-1]狀態轉移:dp[i][j] 為 true 需滿足以下兩個條件之一:
dp[i-1][j] == true 且 s1[i-1] == s3[i+j-1](從 s1 取第 i 個字元)dp[i][j-1] == true 且 s2[j-1] == s3[i+j-1](從 s2 取第 j 個字元)邊界檢查:若 s1.size() + s2.size() != s3.size(),直接回傳 false。
範例:s1 = "aab",s2 = "axy",s3 = "aaxaby"
時間複雜度:O(m × n) — 其中 m = s1.length(),n = s2.length()。需填滿整個二維 DP 表格,每格 O(1)。
空間複雜度:O(m × n) — 二維 DP 陣列。可優化為 O(n)(滾動陣列),因為每列只依賴上一列的值。
1. If len(s1) + len(s2) != len(s3), return false.
2. Initialize (m+1) x (n+1) boolean dp table, all false.
3. Set dp[0][0] = true.
4. Fill dp[i][0] for i in 1..m: dp[i][0] = dp[i-1][0] AND s1[i-1]==s3[i-1].
5. Fill dp[0][j] for j in 1..n: dp[0][j] = dp[0][j-1] AND s2[j-1]==s3[j-1].
6. For i in 1..m, j in 1..n:
- dp[i][j] = (dp[i-1][j] AND s1[i-1]==s3[i+j-1])
OR (dp[i][j-1] AND s2[j-1]==s3[i+j-1])
7. Return dp[m][n].空間優化 DP O(n) 空間:由於每行 dp[i][j] 只依賴 dp[i-1][j](上方)和 dp[i][j-1](左方),可以只維護一維陣列,逐行滾動更新。外層迴圈為 i,內層更新 dp[j]:dp[j] = (dp[j] && s1[i-1]==s3[i+j-1]) || (dp[j-1] && s2[j-1]==s3[i+j-1]),將空間降至 O(n)。
BFS/DFS + 記憶化 O(m × n):將問題視為圖搜索,狀態為 (i, j) 代表已消耗 s1 的 i 個字元和 s2 的 j 個字元。BFS 從 (0,0) 出發,嘗試匹配 s1 或 s2 的下一個字元,用 visited 集合避免重複訪問。與 DP 等效但程式碼風格不同。
s3 可以由 三個 字串交錯而成,DP 的維度需要如何擴展?