Leetcode 97. Interleaving String
Woodyiiiiiii opened this issue · comments
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的情况。