1. 题目
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = “aabcc”,
s2 = “dbbca”,
When s3 = “aadbbcbcac”, return true.
When s3 = “aadbbbaccc”, return false.
2. 思路
递归的思路比较好理解,第一版直接递归,超时了。
加入了结果的cache,在已经计算过的结果里,降低递归的次数,AC。
cache用一个flagi的数组来标识,初始为2,表示还没计算过。如果计算过,则赋值为0或1,代表不匹配和匹配。
3. 代码
耗时:6ms
class Solution {
int flag[512][512];
public:
bool isInterleave(string s1, string s2, string s3) {
int l1 = s1.length();
int l2 = s2.length();
int l3 = s3.length();
if (l1+l2!=l3) { return false; }
for (int i = 0; i < l1+1; i++) {
for (int j = 0; j < l2+1; j++) {
flag[i][j] = 2;
}
}
return isInterleave(s1, 0, s2, 0, s3, 0);
}
bool isInterleave(string& si, int i, string& sj, int j, string& sk, int k) {
if (i == si.length()) { flag[i][j] = sj.substr(j) == sk.substr(k) ? 1 : 0; return flag[i][j] == 1; }
if (j == sj.length()) { flag[i][j] = si.substr(i) == sk.substr(k) ? 1 : 0; return flag[i][j] == 1; }
int r_i = i;
int r_j = j;
while (si[i] != sj[j] && i < si.length() && j < sj.length()) {
if (si[i] == sk[k]) {
i++; k++;
} else if (sj[j] == sk[k]) {
j++; k++;
} else {
flag[r_i][r_j] = 0;
flag[i][j] = 0;
return false;
}
}
if (i == si.length() || j == sj.length()) {
return isInterleave(si, i, sj, j, sk, k);
}
if (si[i] == sk[k]) {
if (flag[i+1][j] == 2) {
flag[i+1][j] = isInterleave(si, i+1, sj, j, sk, k+1) ? 1 : 0;
}
if (flag[i+1][j] == 1) { return true; }
if (flag[i][j+1] == 2) {
flag[i][j+1] = isInterleave(si, i, sj, j+1, sk,k+1) ? 1 : 0;
}
if (flag[i][j+1] == 1) { return true; }
}
flag[i][j] = 0;
return false;
}
};