https://leetcode-cn.com/problems/edit-distance/
https://leetcode-cn.com/problems/edit-distance/solution/zi-di-xiang-shang-he-zi-ding-xiang-xia-by-powcai-3/
最长公共子序列
描述
令 A = a1a2…an,B = b1b2…bn
令 L[ i , j ] 表示 a1a2…ai 和 b1b2…bj 的最长公共子序列的长度
当 A[i] == B[i],L[ i , j ] = L[ i-1 , j-1 ] + 1
当 A[i] != B[i],L[ i , j ] = max{ L[ i-1 , j ] , L[ i , j-1 ] }
eg:
A = horse,B = ros
i为2,j为2时,o == o,L[ ho , ro ] = L[ h , r ] + 1
i为3,j为3时,r != s,L[ hor , ros ] = max{ L[ ho , ros ] , L[ hor , ro ] }
例子
开始时,第一行、第一列均为0
箭头数值记录来源(后续可根据箭头方向恢复出最长公共子序列)
填完是这样的
可以根据箭头方向恢复出最长公共子序列(不唯一)
java实现
public static int LCS(String word1, String word2) {
int[][] maxSub = new int[word1.length()+1][word2.length()+1];
for(int i=1;i<word1.length()+1;i++) {
for(int j=1;j<word2.length()+1;j++) {
if(word1.charAt(i-1)==word2.charAt(j-1)) {
maxSub[i][j] = maxSub[i-1][j-1] + 1;
}else {
maxSub[i][j] = Math.max(maxSub[i-1][j], maxSub[i][j-1]);
}
}
}
return maxSub[word1.length()][word2.length()];
}
最短编辑距离
描述
令 A = a1a2…an,B = b1b2…bn
令 L[ i , j ] 表示 a1a2…ai 和 b1b2…bj 的最短编辑距离
当 A[i] == B[i],L[ i , j ] = L[ i-1 , j-1 ]
当 A[i] != B[i],L[ i , j ] = min{ L[ i-1 , j-1 ] , L[ i-1 , j ] , L[ i , j-1 ] } + 1
其中,L[ i-1 , j-1 ] 代表替换操作,L[ i-1 , j ] 代表删除操作,L[ i , j-1 ] 代表插入操作
eg:
A = horse,B = ros
i为2,j为2时,o == o,L[ ho , ro ] = L[ h , r ],无需继续编辑
i为3,j为3时,r != s,L[ hor , ros ] = min{ L[ ho , ro ] , L[ ho , ros ] , L[ hor , ro ] } + 1
L[ ho , ro ] + 1 代表,在ho已经编辑成ro之后,将r替换成s
L[ ho , ros ] + 1 代表,在ho已经编辑成ros之后,将r删除
L[ hor , ro ] + 1 代表,在hor已经编辑成ro之后,插入s
例子
开始时,第一行为行序号,第一列为列序号
填完是这样的
编辑过程
java实现
public static int minDistance(String word1, String word2) {
int[][] minEdit = new int[word1.length()+1][word2.length()+1];
for(int i=1;i<word1.length()+1;i++) {
minEdit[i][0] = i;
}
for(int i=1;i<word2.length()+1;i++) {
minEdit[0][i] = i;
}
for(int i=1;i<word1.length()+1;i++) {
for(int j=1;j<word2.length()+1;j++) {
if(word1.charAt(i-1)==word2.charAt(j-1)) {
minEdit[i][j] = minEdit[i-1][j-1];
}else {
int min = Math.min(minEdit[i-1][j], minEdit[i][j-1]);
min = Math.min(min, minEdit[i-1][j-1]);
minEdit[i][j] = min+1;
}
}
}
return minEdit[word1.length()][word2.length()];
}