72. 编辑距离
给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例 1:
1 2 3 4 5 6
| 输入: word1 = "horse", word2 = "ros" 输出: 3 解释: horse -> rorse (将 'h' 替换为 'r') rorse -> rose (删除 'r') rose -> ros (删除 'e')
|
示例 2:
1 2 3 4 5 6 7 8
| 输入: word1 = "intention", word2 = "execution" 输出: 5 解释: intention -> inention (删除 't') inention -> enention (将 'i' 替换为 'e') enention -> exention (将 'n' 替换为 'x') exention -> exection (将 'n' 替换为 'c') exection -> execution (插入 'u')
|
思路:
这是一个关于动态规划的问题
这里有一个dp
二维数组,dp[i][j]
表示的是word1
从0到第i
个位置与word2
从0到第j
个位置的编辑距离,那么就可以有动态规划的逻辑
当word1
的第i
个位置与word2
的第j
个位置相同的时候,dp[i][j] = dp[i - 1][j - 1]
,否则:
dp[i][j] = min(dp[i - 1][j] + 1, min(dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1))
这里比较烦恼的是dp数组的初始化问题,就是因为在这里发生了很多bug
正确的初始化方法(见code):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class Solution { public: int minDistance(string word1, string word2) { if(word1.length() == 0 || word2.length() == 0) { return max(word1.length(), word2.length()); } int len1 = word1.length(), len2 = word2.length(); int dp[len1][len2]; dp[0][0] = word1[0] == word2[0] ? 0 : 1; bool flag = word1[0] == word2[0]; for(int i = 1;i < len2;i++) { if(word1[0] == word2[i]) { flag = true; } dp[0][i] = flag ? i : i + 1; } flag = word1[0] == word2[0]; for(int i = 1;i < len1;i++) { if(word1[i] == word2[0]) { flag = true; } dp[i][0] = flag ? i : i + 1; } for(int i = 1;i < len1;i++) { for(int j = 1;j < len2;j++) { if(word1[i] == word2[j]) { dp[i][j] = dp[i - 1][j - 1]; } else { dp[i][j] = min(dp[i - 1][j -1] + 1, min(dp[i - 1][j] + 1, dp[i][j - 1] + 1)); } } } return dp[len1 - 1][len2 - 1]; } };
|