LeetCode Online Judge 题目C# 练习 - 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
"abc" -> "bbdc" : change 'a' to 'b', remove 'd' : 2 steps
1 public static int MinDistance(string word1, string word2) 2 { 3 int[,] matrix = new int[word2.Length + 1, word1.Length + 1]; 4 matrix[0, 0] = 0; 5 6 for (int i = 1; i <= word1.Length; i++) //初始化 第一行 7 matrix[0, i] = i; 8 9 for (int i = 1; i <= word2.Length; i++) //初始化 第一列 10 matrix[i, 0] = i; 11 12 for(int i = 1; i <= word2.Length; i++) 13 { 14 for (int j = 1; j <= word1.Length; j++) 15 { 16 //如果当前两个字符相等,Min(左上角的数,上面的数+1,左边的数+1) 17 //如果不相等, Min(左上角的数+1, 上面的数+1,左边的数+1) 18 int min = Math.Min(matrix[i - 1, j - 1] + (word1[j - 1] == word2[i - 1] ? 0 : 1), matrix[i - 1, j] + 1); 19 min = Math.Min(min, matrix[i, j - 1] + 1); 20 21 matrix[i, j] = min; 22 } 23 } 24 25 return matrix[word2.Length, word1.Length]; 26 }
代码分析:
这题是典型的字符串比较题,DP最适合。
建一个matrix(2d-array), size[word1.Length + 1, word2.Length + 1] 因为前面要加上空字符
例子: "ababd" -> "ccabab"
先初始化matrix如下。意思是,比如"_" -> "cca" = 2 操作是插入'c','c','a',共3步。 "abab" -> "+ "_" 删除'a','b','a','b',共4 步。
_ | a | b | a | b | d | |
_ | 0 | 1 | 2 | 3 | 4 | 5 |
c | 1 | |||||
c | 2 | |||||
a | 3 | |||||
b | 4 | |||||
a | 5 | |||||
b | 6 |
然后按照注释里的方法填满表格,返回最后一个数字(最佳解)
_ | a | b | a | b | d | |
_ | 0 | 1 | 2 | 3 | 4 | 5 |
c | 1 | 1 | 2 | 3 | 4 | 5 |
c | 2 | 2 | 2 | 3 | 4 | 5 |
a | 3 | 2 | 3 | 2 | 3 | 4 |
b | 4 | 3 | 2 | 3 | 2 | 3 |
a | 5 | 4 | 3 | 2 | 3 | 3 |
b | 6 | 5 | 4 | 3 | 2 | 3 |
补充一个递归的做法,但是不建议。。。
1 public static int EditDistance(string a, int aLength, string b, int bLength) 2 { 3 if (aLength == 0) 4 return bLength; 5 if (bLength == 0) 6 return aLength; 7 8 if (a[aLength - 1] == b[bLength - 1]) 9 return EditDistance(a, aLength - 1, b, bLength - 1); 10 else 11 return Math.Min(Math.Min(EditDistance(a, aLength - 1, b, bLength - 1) + 1, 12 EditDistance(a, aLength - 1, b, bLength) + 1), 13 EditDistance(a, aLength, b, bLength - 1) + 1); 14 }