LeetCode 97. 交錯字串
阿新 • • 發佈:2020-07-18
題目連結
題目分析
字串題目,一般不考慮暴力解法,因為極有可能會出現超時的情況(主要是重複搜尋次數太多
這個題很明顯的就是需要我們使用動態規劃去做,一開始我自己也懵逼了,三串的DP?難不成要一個三維狀態陣列嗎,但是仔細分析了一下好像其實並不是的。
因為我們s1的長度加s2的長度必定要等於s3的長度才有可能構成交錯字串,所以我們可以利用這裡的關係去把三位狀態陣列壓縮成二維。
- dp[i][j]代表的是s1的第i-1個字元和s2的第j-1個字元匹配到s3的第i+j-1個字元的地方是否匹配
那麼我們把狀態定下來之後,就是找對應的轉移方程了,其轉移也是非常的容易理解,這裡要從上往下一個一個判斷,因為存在包含關係。
- 如果s1的當前位字元和s2的字元相等,並且s1的字元等於s3的字元,那麼我們需要去判斷要使用哪一個才能使得交錯字串成立,所以dp[i][j] = dp[i-1][j] || dp[i][j-1];
- 如果s1的字元等於s3的字元,那麼很明顯就是要s1往前挪一步,所以dp[i][j] = dp[i-1][j];
- s2字元相等的情況和第二點一樣。
那麼我們還需要base cases,因為有可能單獨s1或者s2都能匹配s3,所以我們要單獨把另外一個字串為空串的情況拿出來分析。
總的來說這個題的狀態轉移和其他的字串匹配很相似,也很容易就寫出來了。
程式碼實現
class Solution { public boolean isInterleave(String s1, String s2, String s3) { if(s1.length() + s2.length() != s3.length()){ return false; } boolean[][] dp = new boolean[s1.length()+1][s2.length()+1]; dp[0][0] = true; for(int i = 0; i < s1.length(); i++){ if(s1.charAt(i) == s3.charAt(i)){ dp[i+1][0] = dp[i][0]; } } for(int i = 0; i < s2.length(); i++){ if(s2.charAt(i) == s3.charAt(i)){ dp[0][i+1] = dp[0][i]; } } for(int i = 1; i < dp.length; i++){ for(int j = 1; j < dp[i].length; j++){ if(s1.charAt(i-1) == s2.charAt(j-1) && s1.charAt(i-1) == s3.charAt(i+j-1)){ dp[i][j] = dp[i-1][j] || dp[i][j-1]; }else if(s1.charAt(i-1) == s3.charAt(i+j-1)){ dp[i][j] = dp[i-1][j]; }else if(s2.charAt(j-1) == s3.charAt(i+j-1)){ dp[i][j] = dp[i][j-1]; } } } return dp[dp.length-1][dp[0].length-1]; } }
總結
DP還是得靠自己慢慢摸索才能提升。