1. 程式人生 > 其它 >LeetCode 0097 Interleaving String

LeetCode 0097 Interleaving String

原題傳送門

1. 題目描述

2. Solution 1

1、思路分析
動態規劃: 設len(s1)=n,len(s2)=m。
1> 狀態定義: f(i, j) 表示s1的前i個元素和s2的前j個元素是否能交錯組成s3的前i+j個元素。
2> 邊界: f(0, 0)=true
3> 狀態轉移方程:
如果s1的第i個 元素和s3的第i+j個元素相等,那麼s1的前i個元素和s2的前j個元素是否能交錯成s3的前i+j個元素取決於s1的前i-1個元素和s2的前j個元素是否能交錯組成s3的前i+j-1個元素,即此時f(i, j)取決於f(i-1, j),在此情況下如果f(i - 1, j)為真,則f(i, j)也為真。同樣的,如果s2的第j個元素和s3的第i+j個元素相等並且f(i, j-1)為真,則f(i, j)也為真。綜上:
f(i, j) = (f(i-1, j) and s1(i-1) = s3(p)) or (f(i, j-1) and s2(j-1) = s3(p)),其中p=i+j-1。

2、程式碼實現

package Q0099.Q0097InterleavingString;


/*
    動態規劃: 設len(s1)=n,len(s2)=m。
    1> 狀態定義: f(i, j) 表示s1的前i個元素和s2的前j個元素是否能交錯組成s3的前i+j個元素。
    2> 邊界: f(0, 0)=true
    3> 狀態轉移方程:
    如果s1的第i個 元素和s3的第i+j個元素相等,那麼s1的前i個元素和s2的前j個元素是否能交錯成s3的前i+j個元素取決於s1的前i-1個元素和s2的前j個
    元素是否能交錯組成s3的前i+j-1個元素,即此時f(i, j)取決於f(i-1, j),在此情況下如果f(i - 1, j)為真,則f(i, j)也為真。同樣的,如果
    s2的第j個元素和s3的第i+j個元素相等並且f(i, j-1)為真,則f(i, j)也為真。綜上:
    f(i, j) = (f(i-1, j) and s1(i-1) = s3(p)) or (f(i, j-1) and s2(j-1) = s3(p)),其中p=i+j-1。
 */
public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n = s1.length(), m = s2.length(), t = s3.length();

        if (n + m != t) return false;

        boolean[][] f = new boolean[n + 1][m + 1];

        f[0][0] = true;
        for (int i = 0; i <= n; ++i) {
            for (int j = 0; j <= m; ++j) {
                int p = i + j - 1;
                if (i > 0) {
                    f[i][j] = f[i][j] || (f[i - 1][j] && s1.charAt(i - 1) == s3.charAt(p));
                }
                if (j > 0) {
                    f[i][j] = f[i][j] || (f[i][j - 1] && s2.charAt(j - 1) == s3.charAt(p));
                }
            }
        }
        return f[n][m];
    }
}

3、複雜度分析
時間複雜度: O(nm)
空間複雜度: O(nm)

3. Solution 2

1、思路分析
使用滾動陣列優化空間複雜度。因為這裡陣列f的第i行只和第i-1行相關,所以我們可以用滾動陣列優化這個動態規劃,這樣空間複雜度可以變成O(m)。

2、程式碼實現

package Q0099.Q0097InterleavingString;

public class Solution2 {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n = s1.length(), m = s2.length(), t = s3.length();

        if (n + m != t) return false;

        boolean[] f = new boolean[m + 1];
        f[0] = true;
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                int p = i + j - 1;
                if (i > 0)
                    f[j] = f[j] && s1.charAt(i - 1) == s3.charAt(p);
                if (j > 0)
                    f[j] = f[j] || (f[j - 1] && s2.charAt(j - 1) == s3.charAt(p));
            }
        }
        return f[m];
    }
}

3、複雜度分析
時間複雜度: O(nm)
空間複雜度: O(m)