题目描述
求两个字符串的编辑距离:
具体操作方法为:
a) Insert a character
b) Delete a character
c) Replace a character
比如,对于“abcd”和"abcde"可以认为最少需要通过增加/减少一个'e'得到,则编辑距离为1。
思路:
若第一个字符是相同的,则考虑两个字符串从第二个字符开始的相似距离即可;
若第一个字符不同,可以选择的方法有:
1.删除A串第一个字符,然后计算A[2,.....lenA]和B[1,......lenB]的距离;
2.删除B串第一个字符,然后计算A[1,.....lenA]和B[2,......lenB]的距离;
3.修改A串的第一个字符为B串的第一个字符,然后计算A[2,.....lenA]和B[2,......lenB]的距离;
4.修改B串的第一个字符为A串的第一个字符,然后计算A[2,.....lenA]和B[2,......lenB]的距离;
5.增加B串的第一个字符到A串第一个字符之前,然后计算A[1,.....lenA]和B[2,......lenB]的距离;
6.增加A串的第一个字符到B串第一个字符之前,然后计算A[2,.....lenA]和B[1,......lenB]的距离;
可以看出都是:
1.一步操作后,再将A[2,.....lenA]和B[1,......lenB]变为相同的字符串;
2.一步操作后,再将A[1,.....lenA]和B[2,......lenB]变为相同的字符串;
3.一步操作后,再将A[2,.....lenA]和B[2,......lenB]变为相同的字符串;
递归程序:
public class Solution {
public int minDistance(String word1, String word2) {
if(word1.length() == 0)//递归边界时的情况;
return word2.length();
if(word2.length() == 0)
return word1.length();
if(word1.charAt(0) == word2.charAt(0))
return minDistance(word1.substring(1),word2.substring(1));
int a=minDistance(word1.substring(1),word2.substring(1));
int b=minDistance(word1.substring(1),word2);
int c=minDistance(word1,word2.substring(1));
return min(a,b,c)+1;
}
public int min(int a,int b,int c)
{
int min=a<b?a:b;
return min<c?min:c;
}
}
DP:
如果我们用 i 表示当前字符串 A 的下标,j 表示当前字符串 B 的下标。 如果我们用d[i, j] 来表示A[1, ... , i] B[1, ... , j] 之间的最少编辑操作数。那么我们会有以下发现:
1. d[0, j] = j;
2. d[i, 0] = i;
3. d[i, j] = d[i-1, j - 1] if A[i] == B[j]
4. d[i, j] = min(d[i-1, j - 1], d[i, j - 1], d[i-1, j]) + 1 if A[i] != B[j]
找出最小编辑操作数,从底自上判断
public class Solution {
public int minDistance(String s1, String s2) {
//dp[i][j]表示s1长为i,s2长为j时的编辑距离;
int[][] dp=new int[s1.length()+1][s2.length()+1];
//S1长度为0时,返回s2的长度;
for(int i=0;i<=s1.length();i++)
{
dp[i][0]=i;
}
//s2长度为0时,返回s1的长度;
for(int j=0;j<=s2.length();j++)
{
dp[0][j]=j;
}
//一般情况
for(int i=1;i<=s1.length();i++)
{
for(int j=1;j<=s2.length();j++)
{
//当s1第i个字符和s2第j个字符相同时:
if(s1.charAt(i-1) == s2.charAt(j-1))
{
dp[i][j]=dp[i-1][j-1];
}
//当s1第i个字符和s2第j个字符不同时:
else
{
//dp[i-1][j-1]为s1的第i个字符变换为s2的第j个字符或者s2变换的情况;
//dp[i-1][j]为删除或插入的情况;
dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1;
}
}
}
return dp[s1.length()][s2.length()];
}
public int min(int a,int b,int c)
{
int min=a<b?a:b;
return min<c?min:c;
}
}