/** * 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 * * Tags: DP, String */ class EditDist { public static void main(String[] args) { } /** * DP, O(nm) Time, O(nm) Space * Searching for a path (sequence of edits) from the start string to the * final string * For two strings, X of length n, Y of length m * Define D(i,j): the edit distance between X[1..i] and Y[1..j] * The edit distance between X and Y is thus D(n,m) * * Initialization: D(i,0) = i, D(0,j) = j * 1. D(i, j) = min(D(i - 1, j) + 1, D(i, j - 1) + 1, D(i - 1, j - 1) + 0 * or 1), 0 is X(i) = Y(j), 1 if X(i) != Y(j) * D(N, M) is distance * * Note that f[i][j] only depends on f[i-1][j-1], f[i-1][j] and f[i][j-1], * therefore we can reduce the space to O(n) by using only the (i-1)th * array and previous updated element(f[i][j-1]). */ public static int minDistance(String word1, String word2) { if (word1.equals(word2)) return 0; int m = word1.length(); int n = word2.length(); int[][] d = new int[m + 1][n + 1]; d[0][0] = 0; for (int i = 1; i < m + 1; i++) d[i][0] = i; for (int j = 1; j < n + 1; j++) d[0][j] = j; for (int i = 1; i < m + 1; i++) { for (int j = 1; j < n + 1; j++) { d[i][j] = Math.min(Math.min(d[i][j - 1] + 1, d[i - 1][j] + 1), word1.charAt(i - 1) == word2.charAt(j - 1) ? d[i - 1][j - 1] : d[i - 1][j - 1] + 1); } } return d[m][n]; } /** * Optimal DP. Reduce table to a row. */ public static int minDistanceOptimal(String word1, String word2) { if (word1.equals(word2)) return 0; int m = word1.length(); int n = word2.length(); int[] d = new int[n + 1]; d[0] = 0; for (int j = 1; j < n + 1; j++) d[j] = j; for (int i = 1; i < m + 1; i++) { int prev = d[0]; d[0] += 1; for (int j = 1; j < n + 1; j++) { int temp = d[j]; d[j] = Math.min(Math.min(d[j - 1] + 1, d[j] + 1), word1.charAt(i - 1) == word2.charAt(j - 1) ? prev : prev + 1); prev = temp; } } return d[n]; } }