思路:
又是一道典型DP!
我们将人生划为诡异的阶段
我们把这个世界表为丰富的状态
package DP; import java.util.Arrays; /** * 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 */ public class EditDistance { static int[][] dist = null; public static void main(String[] args) { String word1 = "sdfsssjdfhsb"; String word2 = "cvdsfadfgkdfgj"; dist = new int[word1.length()+1][word2.length()+1]; for(int[] row : dist){ Arrays.fill(row, -1); } System.out.println(minDistance(word1, word2)); System.out.println(minDistance2(word1, word2)); } public static int min3(int a, int b, int c){ return Math.min(Math.min(a, b), c); } // DP bottom-up public static int minDistance(String word1, String word2) { int[][] distance = new int[word1.length()+1][word2.length()+1]; // 边界情况:当其中一个string为空时,只要一直添加或删除就可以 for(int i=0; i<=word1.length(); i++){ distance[i][0] = i; } for(int j=1; j<=word2.length(); j++){ distance[0][j] = j; } // 递推,[i][j]处可以由左,上,左上3种情况而来 for(int i=1; i<=word1.length(); i++){ for(int j=1; j<=word2.length(); j++){ distance[i][j] = min3(distance[i-1][j]+1, // 从上演变 distance[i][j-1]+1, // 从左演变 distance[i-1][j-1]+(word1.charAt(i-1)==word2.charAt(j-1) ? 0 : 1)); // 从左上演变,考虑是否需要替换 } } return distance[word1.length()][word2.length()]; // 返回右下角 } // 递归,太慢 public static int minDistance2(String word1, String word2) { // return rec(word1, word1.length(), word2, word2.length()); return rec2(word1, word1.length(), word2, word2.length()); } public static int rec(String word1, int len1, String word2, int len2){ if(len1 == 0){ return len2; } if(len2 == 0){ return len1; } if(word1.charAt(len1-1) == word2.charAt(len2-1)){ return rec(word1, len1-1, word2, len2-1); }else{ return min3(rec(word1, len1-1, word2, len2-1) + 1, rec(word1, len1, word2, len2-1) + 1, rec(word1, len1-1, word2, len2) + 1); } } // 添加全局数组,保存状态,用空间换时间 DP top-down public static int rec2(String word1, int len1, String word2, int len2){ if(len1 == 0){ return len2; } if(len2 == 0){ return len1; } if(word1.charAt(len1-1) == word2.charAt(len2-1)){ if(dist[len1-1][len2-1] == -1){ dist[len1-1][len2-1] = rec2(word1, len1-1, word2, len2-1); } return dist[len1-1][len2-1]; }else{ if(dist[len1-1][len2-1] == -1){ dist[len1-1][len2-1] = rec2(word1, len1-1, word2, len2-1); } if(dist[len1][len2-1] == -1){ dist[len1][len2-1] = rec2(word1, len1, word2, len2-1); } if(dist[len1-1][len2] == -1){ dist[len1-1][len2] = rec2(word1, len1-1, word2, len2); } dist[len1][len2] = min3(dist[len1-1][len2-1]+1, dist[len1][len2-1]+1, dist[len1-1][len2]+1); return dist[len1][len2]; } } }
Ref:
这个视频讲的特别好!
http://www.youtube.com/watch?v=CB425OsE4Fo&list=PL0174E49C0E0DD5C8&index=35
https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Java
http://www.cnblogs.com/etcow/archive/2012/08/30/2662985.html
http://blog.csdn.net/alexander_xfl/article/details/11557185
http://www.cs.uiuc.edu/~jeffe/teaching/algorithms/
http://courses.engr.illinois.edu/cs473/lectures.html
public class Solution { public int minDistance(String word1, String word2) { int len1 = word1.length(); int len2 = word2.length(); if(len1 == 0) { return len2; } if(len2 == 0) { return len1; } int[][] ed = new int[len1+1][len2+1]; for(int i=0; i<=len1; i++) { ed[i][0] = i; } for(int j=0; j<=len2; j++) { ed[0][j] = j; } for(int i=1; i<=len1; i++) { for(int j=1; j<=len2; j++) { if(word1.charAt(i-1) == word2.charAt(j-1)) { ed[i][j] = ed[i-1][j-1]; } else { ed[i][j] = Math.min(ed[i-1][j-1], Math.min(ed[i-1][j], ed[i][j-1])) + 1; } } } return ed[len1][len2]; } }