交錯字串 | Medium | LeetCode#97. Interleaving String
題目敘述

- 題目難度:
Medium - 題目敘述:給定字串
s1,s2,s3,檢查s3是否是由s1以及s2交錯組合而成 (Interleaving)。
s = s1 + s2 + s3 +... + snt = t1 + t2 + t3 + ... + tn|n-m| <= 1
Interleaving: s1+t1+s2+t2+s3+t3+... or t1+s1+t2+s2+t3+s3+...
解法
一開始的想法
1 | bool helper(string s3,string s1, string s2, string temp, int start){ |
這樣的解法,對於相同的 start,會重複計算大量子問題。因此會超時!
Recursive + Memoization
1 | class Solution { |
這裡宣告了用於儲存重複計算結果的 2D陣列,vector<vector<int>> dp,在 isInterleave 函數中初始化為 (n+1) x (m+1),helper 函數中改成不以 for 去做迭代,而是用用遞迴的方式在每一層檢查交錯,另外在先前得解法中沒有考慮到的是, s3 的長度會是 s1 跟 s2 的長度加總,因此不能用 s1[i]==s3[i] 的方式去迭代 ,這樣會超出 s1 的長度限制。因此我們透過 s1[i] == s3[i+j] 來檢查交錯,如果相等,那就按照當前的 s1的位置繼續遞迴檢查下去 helper(s3,s1,s2, i+1,j) 並且將結果保存到 result ,如果在當前這層,result 結果為 false 則改成檢查 s2,如果 s2[j] == s3[i+j] 則可以接續當前 s2的位置繼續遞迴檢查 helper(s3,s1,s2,i,j+1),結果一樣保存到 result。
為了應對大量重複計算,在每一層遞迴季算中,都會將結果的 result 保存到對應的 dp[i][j] 代表以該位置i,j切割 s1, s2 是否能夠交錯組合成 s3。若有重複的計算結果也直接回傳 dp[i][j],以減省時間。
執行結果

複雜度
| 複雜度類型 | 時間/空間複雜度 | 分析過程 |
|---|---|---|
| 時間複雜度 | $O(n * m)$ | 遞迴檢查每個狀態,且使用 dp 陣列避免重複計算,共有 n * m 狀態需要計算 |
| 空間複雜度 | $O(n * m)$ | 需要一個大小為 n * m 的二維 dp 陣列來儲存每個狀態結果,遞迴堆疊使用額外空間 $O(d)$ |
本部落格所有文章除特別聲明外,均採用CC BY-NC-SA 4.0 授權協議。轉載請註明來源 Kevin Liu's 部落格 || Technical || Travel!
評論










