其他分享
首页 > 其他分享> > 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)

标签:charAt,s3,s2,Interleaving,元素,复杂度,0097,LeetCode,s1
来源: https://www.cnblogs.com/junstat/p/16227197.html