leetcode 72. Edit Distance
2016-09-15 14:53
218 查看
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
例如:
word1:a
word2:ab
这样可以在word1后面增加一个字符b来使得word1变成word2。这时只需1步。
例如:
word1:mart
word2:karma
可以将word1的第一个字符‘m’换成‘k’,第4个字符’t’换成‘m’,最后增加一个字符’a’。这时只需3步。
例如:
word1:hehe123
word2:hehe
可以将word1后面的三个字符“123”全部删掉。这时只需3步。
上面的代码是自己AC的,总感觉写的很戳,于是找了下网上的写法,发现差距不是一点半点。不能忘记历史,所以也粘贴过来了。
代码可以写的越来越好的。大牛也是这么练就的。
先上代码:
究其原因,还是没有理清问题,没有找准递推公式:
当word1的下标都小于0了,要变成word2,只要增加 字符就行了。
当word2的下标小于0了,word1要变成word2,只要删除 字符就行了。
递推代码也要表示出word1或者word2下标小于0的情况。但是数组的下标都是从0开始的,无法表示负数下标,因此可以用二维数组中,下标为0的表示单词没有字符了,也就是说,下标表示单词的字符个数。
这个问题详见这篇博文:
http://www.dreamxu.com/books/dsa/dp/edit-distance.html
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
例如:
word1:a
word2:ab
这样可以在word1后面增加一个字符b来使得word1变成word2。这时只需1步。
例如:
word1:mart
word2:karma
可以将word1的第一个字符‘m’换成‘k’,第4个字符’t’换成‘m’,最后增加一个字符’a’。这时只需3步。
例如:
word1:hehe123
word2:hehe
可以将word1后面的三个字符“123”全部删掉。这时只需3步。
递归代码(记忆化搜索优化)
public class Solution { public static final int MAX_INT = 100000; public static int[][] result; public int search(int x, int y, String word1, String word2) { if (x == 0 && y == 0) { if (word1.charAt(x) == word2.charAt(y)) { return 0; } else { return 1; } } if (x < 0 && y >= 0) { return y+1; //增加 } if (x >= 0 && y < 0) { return x+1; //删除 } //记忆化搜索 if(result[x][y] >= 0) { return result[x][y]; } //这几个初始值,不要初始化为0,否则最终的结果是0 int a = MAX_INT, b = MAX_INT, c = MAX_INT, d = MAX_INT; if (word1.charAt(x) == word2.charAt(y)) { a = search(x-1, y-1, word1, word2); } b = search(x-1, y, word1, word2) + 1; //删除 c = search(x, y-1, word1, word2) + 1; //增加 d = search(x-1, y-1, word1, word2) + 1; //替换 result[x][y] = Math.min(Math.min(Math.min(a, b), c),d); return result[x][y]; } public int minDistance(String word1, String word2) { if (word1.length() == 0 || word2.length() == 0) { return Math.abs(word1.length() - word2.length()); } result = new int[word1.length()][word2.length()]; for(int i = 0; i < word1.length(); i++) { for(int j = 0; j < word2.length(); j++) { result[i][j] = -1; } } return search(word1.length()-1, word2.length()-1, word1, word2); } }
上面的代码是自己AC的,总感觉写的很戳,于是找了下网上的写法,发现差距不是一点半点。不能忘记历史,所以也粘贴过来了。
代码可以写的越来越好的。大牛也是这么练就的。
先上代码:
public int search(int x, int y, String word1, String word2) { if ( x < 0) { return y+1; } if (y < 0) { return x+1; } if (result[x][y] >= 0) { return result[x][y]; } if (word1.charAt(x) == word2.charAt(y)) { result[x][y] = search(x-1, y-1, word1, word2); } else { int a = 0, b = 0, c = 0; //替换 a = search(x-1, y-1, word1, word2) + 1; //增加 b = search(x, y-1, word1, word2) + 1; //删除 c = search(x-1, y, word1, word2) + 1; result[x][y] = Math.min(Math.min(a, b), c); } return result[x][y]; } public int minDistance(String word1, String word2) { result = new int[word1.length()][word2.length()]; for(int i = 0; i < word1.length(); i++) { for(int j = 0; j < word2.length(); j++) { result[i][j] = -1; } } return search(word1.length()-1, word2.length()-1, word1, word2); }
究其原因,还是没有理清问题,没有找准递推公式:
当word1的下标都小于0了,要变成word2,只要增加 字符就行了。
当word2的下标小于0了,word1要变成word2,只要删除 字符就行了。
递推代码
public int minDistance(String word1, String word2) { if (word1.length() == 0 || word2.length() == 0) { return Math.abs(word1.length() - word2.length()); } result = new int[word1.length()+1][word2.length()+1]; for(int i = 0; i < word1.length()+1; i++) { for(int j = 0; j < word2.length()+1; j++) { result[i][j] = -1; } } for (int j = 0; j < word2.length()+1; j++) { result[0][j] = j; } int a = MAX_INT, b = MAX_INT, c = MAX_INT; for (int i = 1; i < word1.length()+1; i++) { result[i][0] = i; for (int j = 1; j < word2.length()+1; j++) { if (word1.charAt(i-1) == word2.charAt(j-1)) { result[i][j] = result[i-1][j-1]; } else { a = result[i-1][j] + 1; //删除 b = result[i][j-1] + 1; //增加 c = result[i-1][j-1] + 1; //替换 result[i][j] = Math.min(Math.min(a, b), c); } } } return result[word1.length()][word2.length()]; }
递推代码也要表示出word1或者word2下标小于0的情况。但是数组的下标都是从0开始的,无法表示负数下标,因此可以用二维数组中,下标为0的表示单词没有字符了,也就是说,下标表示单词的字符个数。
这个问题详见这篇博文:
http://www.dreamxu.com/books/dsa/dp/edit-distance.html
相关文章推荐
- [leetcode]72. Edit Distance(Java)
- 72. Edit Distance , LeetCode
- LeetCode 72. Edit Distance
- [leetcode] 72. Edit Distance 解题报告
- Leetcode 72. Edit Distance
- 第九周 leetcode 72. Edit Distance(Hard)
- leetcode-72. Edit Distance
- LeetCode 72. Edit Distance-----Python实现
- Leetcode:72. Edit Distance
- [LeetCode] 72. Edit Distance 编辑距离
- LeetCode-72. Edit Distance (JAVA)字符串最小编辑距离DP&DFS
- leetcode 72. Edit Distance
- leetcode 72. Edit Distance
- Leetcode 72. Edit Distance
- [leetcode] 72. Edit Distance
- LeetCode dynamic programming 72. Edit Distance
- 【leetcode】72. Edit Distance【java】
- leetcode - 72. Edit Distance和 583. Delete Operation for Two Strings
- 【LeetCode】72. Edit Distance
- leetcode 72. Edit Distance