Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 97. Interleaving String

Woodyiiiiiii opened this issue · comments

97. Interleaving String

97. Interleaving String

这道题我没做出来,实在是屈辱,要好好记录下了。

我一开始的想法是,这很显然是DP。那接下来该如何设置DP呢?具体来说如何设置参数及缓存?我的做法是两个参数,s3的标点和s1/s2的标点,再加一个sign标志前者是哪一个的光点。但我发现,有问题,因为s1和s2的标点都要分别记录。

然后我就卡在这里了,然后已经花费了大量时间。

关键是要改变参数,重新设置缓存。根据时间复杂度,显然我们只能从s1 | s2 | s3取其二,最重要的当然是s1和s2。所以就以这两个为参数,最多加一个大小为2的sign。

继续定义缓存,结合s3,可以这样设置,dfs(i,j)表示以i为节点的s1和以j为节点的s2能否构成以i+j为起点的s3。那这样就很容易写出代码了(其实可以发现,sign可以丢掉,因为必会满足题目条件中的n和m的差值为1)。

class Solution {
    String s1, s2, s3;
    int[][] memo;
    int n1, n2, n3;

    public boolean isInterleave(String s1, String s2, String s3) {
        this.s1 = s1; this.s2 = s2; this.s3 = s3;
        n1 = s1.length(); n2 = s2.length(); n3 = s3.length();
        if (n1 + n2 != n3) return false;
        memo = new int[n1][n2];
        for (int[] row : memo) Arrays.fill(row, -1);
        return dfs(0, 0);
    }

    private boolean dfs(int i, int j) {
        if (i >= n1 && j >= n2) return true;
        if (i < n1 && j < n2 && memo[i][j] != -1) return memo[i][j] == 1;

        int ans = 0;
        if (i < n1 && s1.charAt(i) == s3.charAt(i + j)) {
            ans |= dfs(i + 1, j) ? 1 : 0;
        }
        if (ans == 0 && j < n2 && s2.charAt(j) == s3.charAt(i + j)) {
            ans |= dfs(i, j + 1) ? 1 : 0;
        }

        if (i < n1 && j < n2) memo[i][j] = ans;
        return ans == 1;
    }
}

如果改成递推的写法,则要注意n1和n2为0的情况。