子数组/子串 连续
子序列 不一定连续
通过反证法,说明了第一个不能忽略的问题。
能够得知dfs(i - 1,j)再往下递归可以包含dfs(i - 1,j-1),故没必要再写dfs(i - 1,j-1)。
完整代码如下(使用二维数组);
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
char[] s = text1.toCharArray(), t = text2.toCharArray();
int n = s.length, m = t.length;
int[][] f = new int[n + 1][m + 1];
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j){
if(s[i] == t[j]) {
f[i + 1][j + 1] = f[i][j] + 1;
} else {
f[i + 1][j + 1] = Math.max(f[i][j + 1], f[i + 1][j]);
}
}
}
return f[n][m];
}
}
使用一维数组,当前数组使用的位置是左上,上和左,其中使用一维数组的话左上方数据会被覆盖,因此可以采用pre来记录左上方的数据,此题中最左侧一定是0,所以pre初始化为0,完整代码如下:
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
char[] s = text1.toCharArray(), t = text2.toCharArray();
int n = s.length, m = t.length;
int[] f = new int[m + 1];
for (int i = 0; i < n; ++i){
int pre = 0;
for (int j = 0; j < m; ++j){
int tmp = f[j+1];
if(s[i] == t[j]) {
f[j + 1] = pre + 1;
} else {
f[j + 1] = Math.max(f[j + 1], f[j]);
}
pre = tmp;
}
}
return f[m];
}
}
和上一题类似,
上代码:
初始化值有变化。
class Solution {
public int minDistance(String text1, String text2) {
char[] s = text1.toCharArray(), t = text2.toCharArray();
int n = s.length, m = t.length;
int[][] f = new int[n + 1][m + 1];
for (int j = 1; j <= m; ++j) f[0][j] = j;
for (int i = 0; i < n; ++i) {
f[i + 1][0] = i + 1;
for (int j = 0; j < m; ++j)
f[i + 1][j + 1] = s[i] == t[j] ? f[i][j] :
Math.min(Math.min(f[i][j + 1], f[i + 1][j]), f[i][j]) + 1;
}
return f[n][m];
}
}
一维数组:
class Solution {
public int minDistance(String text1, String text2) {
char[] t = text2.toCharArray();
int m = t.length;
int[] f = new int[m + 1];
for (int j = 1; j <= m; j++) f[j] = j;
for (char x : text1.toCharArray()) {
int pre = f[0];
++f[0];
for (int j = 0; j < m; ++j) {
int tmp = f[j + 1];
f[j + 1] = x == t[j] ? pre : Math.min(Math.min(f[j + 1], f[j]), pre) + 1;
pre = tmp;
}
}
return f[m];
}
}