1. 程式人生 > >LeetCode Interleaving String

LeetCode Interleaving String

這是一道DP題,用boolean陣列dp維護歷史資料,dp[i][j]表示長度為i的s1和長度為j的s2能否組成長度為 i+j 的s3.

遞推式是若當前s3的最後一個char與s1的最後一個char相同,並且dp[i-1][j]為true, 那麼dp[i][j]為true;

或者當前s3的最後一個char與s2的最後一個char相同,並且dp[i][j-1]為true, 那麼dp[i][j]為true, 兩者是 或 的關係。

初始化第一排時就是s2長度為0時,看s3和s1最後一個char若相同 並且 s1的前一個字元對應的dp是true, 那麼返回就是true; 第一列同理。

Note: 1. dp的大小是 (len1+1) * (len2+1). dp[0][0] = true是s1,s2,s3長度都為0的情況。

2. for loop時 i 是 <= 而不是< len1.

3. 初始化第一行第一列時別忘了校驗前一個dp的值, 如dp[i-][0].

4. 本題可以使用降維來做。

AC Java:

public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        if(s3.length() != s1.length()+s2.length()){
            return false;
        }
        int len1 = s1.length();
        int len2 = s2.length();
        boolean [][] dp = new boolean[len1+1][len2+1];
        dp[0][0] = true;
        for(int i = 1; i<=len1; i++){   //error
            if(s1.charAt(i-1) == s3.charAt(i-1) && dp[i-1][0]){ //error
                dp[i][0] = true;
            }
        }
        for(int j = 1; j<=len2; j++){
            if(s2.charAt(j-1) == s3.charAt(j-1) && dp[0][j-1]){
                dp[0][j] = true;
            }
        }
        
        for(int i = 1; i<=len1; i++){
            for(int j =1; j<=len2; j++){
                char c = s3.charAt(i+j-1);
                if(c == s1.charAt(i-1) && dp[i-1][j]){
                    dp[i][j] = true;
                }
                if(c == s2.charAt(j-1) && dp[i][j-1]){
                    dp[i][j] = true;
                }
            }
        }
        return dp[len1][len2];
    }
}