首页 > 代码库 > Edit Distance
Edit Distance
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
思路就是用这三种方式分别去找最小的,递归做,贴一下代码
1 public int minDistance(String word1, String word2) { 2 if (word1.equals(word2)) { 3 return 0; 4 } 5 if (word1.length() < word2.length()) { 6 String t = word2; 7 word2 = word1; 8 word1 = t; 9 } 10 int pos = 0; 11 for (; pos < word2.length(); pos++) { 12 if (word1.charAt(pos) != word2.charAt(pos)) { 13 break; 14 } 15 } 16 if (pos == word2.length()) { 17 return word1.length() - word2.length(); 18 } else { 19 int add = 1 + minDistance(word1.substring(pos), word1.charAt(pos) 20 + word2.substring(pos)); 21 int delete = 1 + minDistance( 22 pos == word1.length() - 1 ? "" : word1.substring(pos + 1), 23 word2.substring(pos)); 24 int change = 1 + minDistance( 25 pos == word1.length() - 1 ? "" : word1.substring(pos + 1), 26 pos == word2.length() - 1 ? "" : word2.substring(pos + 1)); 27 add = add > delete ? delete : add; 28 change = change > add ? add : change; 29 return change; 30 } 31 }
然后发现超时了0.0 忽然想起来编程之美上有这个题,查了一下,在第三章,书上的代码和我这差不多啊。。。编程之美上的解法都过不了是么。。。
分析了一下,由于多次递归,时间大部分都消耗在递归上了。
假设word1的长度为i,word2的长度为j
则word1与word2的距离只可能与这三种情况有关:
1.word1.substring(0,i)与word2之间的距离(删除)
2.word1与word2.substring(0,j)之间的距离(添加)
3.word1.substring(0,i)与word2.substring(0,j)之间的距离(更改或不变)
因此,可以将刚才自底向上的解法转化为自顶向下去计算,这样就消除了递归
最初设计的是word1.length()-1*word2.length()-1的矩阵grid,但是在矩阵grid[0][0]赋值的时候遇到了问题,因为最短距离时,word1[0]与word2[0]不一定对应,因此,多加一行一列,grid[i][j]表示word1的(0,i)子串与word2的(0,j)子串的最小距离,如下表所示:
以word1=sea,word2=eat为例:
“” “” | “” “e” | "" "ea" | "" "eat" |
"s" "" | "s" "e" | "s" "ea" | "s" "eat" |
"se" "" | "se" "e" | "se" "ea" | "se" "eat" |
"sea" "" | "sea" "e" | "sea" "ea" | "sea" "eat" |
gird[i][j] = min(grid[i-1][j]+1,grid[i][j-1]+1,gird[i-1][j-1]+(word1.charAt(i)==word2.charAt(j)?0:1));
第0行和第0列要判断边界条件,初始化grid[0][0]=0;
结果就是矩阵grid右下角元素的值,代码如下:
1 public int minDistance(String word1, String word2) { 2 if(word1.equals("")){ 3 return word2.length(); 4 } 5 if(word2.equals("")){ 6 return word1.length(); 7 } 8 int grid[][] = new int[word1.length()+1][word2.length()+1]; 9 for (int i = 0; i <= word1.length(); i++) { 10 for (int j = 0; j <= word2.length(); j++) { 11 if (i == 0 && j == 0) { 12 grid[i][j] = 0; 13 } else if (i == 0) { 14 grid[i][j] = grid[i][j - 1] + 1; 15 } else if (j == 0) { 16 grid[i][j] = grid[i - 1][j] + 1; 17 } else { 18 grid[i][j] = grid[i - 1][j] > grid[i][j - 1] ? grid[i][j - 1] + 1 19 : grid[i - 1][j] + 1; 20 int count = 0; 21 if(word1.charAt(i-1)!=word2.charAt(j-1)){ 22 count = 1; 23 } 24 grid[i][j] = grid[i][j]<grid[i-1][j-1]+count?grid[i][j]:grid[i-1][j-1]+count; 25 } 26 } 27 } 28 return grid[word1.length()][word2.length()]; 29 }