我正在尝试使用自下而上的动态编程来编写两个String对象的LCS。我能够使O(mn)
空间正常工作。但是,正如我所看到的,我不需要所有以前的列。所以,我尝试修改它以使其适合2列,因此空间变为O(m)
。但是,它不适用于所有输入(例如,对此:abcabc
和abcbcca
)。我在这里错过了什么?不是HW,不是没有竞争。练习DP。
public int longestCommonSubsequence(String input) {
char[] firstStr = this.string.toCharArray();
char[] secondStr = input.toCharArray();
int[][] maxLength = new int[firstStr.length+1][2];
for(int i=0; i <= firstStr.length; i++) {
maxLength[i][0] = 0;
}
for(int j=0; j < 2; j++) {
maxLength[0][j] = 0;
}
for(int i=0; i < firstStr.length; i++) {
for(int j=0; j < secondStr.length; j++) {
if(firstStr[i] == secondStr[j]) {
maxLength[i+1][1] = 1 + maxLength[i][0];
}
else {
maxLength[i+1][1] = maxLength[i][1]>maxLength[i+1][0]?maxLength[i][1]:maxLength[i+1][0];
}
}
//Copy second row to first row
for(int l =0; l < firstStr.length; l++) {
maxLength[l][0] = maxLength[l][1];
}
}
return maxLength[firstStr.length -1][0];
}
答案 0 :(得分:0)
这有两个问题:
if(firstStr[i] == secondStr[j]) {
maxLength[i+1][1] = 1 + maxLength[i][0];
// check here if maxLength[i+1][1] is greather than the last max length
}
else {
maxLength[i+1][1] = maxLength[i][1]>maxLength[i+1][0]?maxLength[i][1]:maxLength[i+1][0];
// absolutely wrong: maxLength[i+1][1] = 0;
}
这里可以看到微优化算法。
public static int lcs(String s0, String s1) {
int maxLength = 0;
int [][]lengths = new int[2][s1.length()+1];
for (int i = 0; i < s0.length(); i++) {
for (int j = 0; j < s1.length(); j++) {
if (s0.charAt(i) == s1.charAt(j)) {
lengths[0][j+1] = lengths[1][j] + 1;
if (lengths[0][j+1] > maxLength) {
maxLength = lengths[0][j+1];
}
} else {
lengths[0][j+1] = 0;
}
}
int []temp = lengths[0];
lengths[0] = lengths[1];
lengths[1] = temp;
}
return maxLength;
}