地址:https://leetcode.com/problems/edit-distance/
题目:
Given two words word1
and word2
, find the minimum number of operations required to convert word1
to word2
.
You have the following 3 operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
Example 1:
Input: word1 = “horse”, word2 = “ros”
Output: 3
Explanation:
horse -> rorse (replace ‘h’ with ‘r’)
rorse -> rose (remove ‘r’)
rose -> ros (remove ‘e’)
Example 2:
Input: word1 = “intention”, word2 = “execution”
Output: 5
Explanation:
intention -> inention (remove ‘t’)
inention -> enention (replace ‘i’ with ‘e’)
enention -> exention (replace ‘n’ with ‘x’)
exention -> exection (replace ‘n’ with ‘c’)
exection -> execution (insert ‘u’)
理解:
求两个字符串的编辑距离。
编辑距离的定义是:从字符串A到字符串B,中间需要的最少操作权重
大概就是通过插入,删除和替换操作,让word1
变成word2
的次数。
实现:
解答里给出的代码倒是能照着敲出来,但是并没有看懂为什么。
看到大神给出的解释Edit Distance,理解后自己也解释一下:
使用数组dist[i][j]
表示字符串word1[0:i-1]
和word2[0:j-1]
的编辑距离,也就是说通过修改,此时word1[0:i-1]
和word2[0:j-1]
已经是相同的字符串了。
如何求解dist[i][j]
呢?
- 如果
word1[i-1]==word2[j-1]
,说明最后的两个字符也是相同的,不需要改变,则
d i s t [ i ] [ j ] = d i s t [ i − 1 ] [ j − 1 ] dist[i][j]=dist[i-1][j-1] dist[i][j]=dist[i−1][j−1] - 否则,我们有下面几种方法修改
d i s t [ i ] [ j ] = m i n ( d i s t [ i − 1 ] [ j − 1 ] , d i s t [ i − 1 ] [ j ] , d i s t [ i ] [ j − 1 ] ) + 1 dist[i][j]=min(dist[i-1][j-1],dist[i-1][j],dist[i][j-1])+1 dist[i][j]=min(dist[i−1][j−1],dist[i−1][j],dist[i][j−1])+1- 把
word1[i-1]
替换为word2[j-1]
,也就是说,需要在dist[i-1][j-1]
的基础上,修改word1[i-1]
- 把
word1[i-1]
删除,因为dist[i-1][j]
给出了word1[0:i-2]
修改为word2[0:j-1]
的次数,我们只需要把word1[i-1]
删除,又可以重新使得两个字符串相同 - 在
word1[i-2]
后面插入word2[j-1]
,因为dist[i][j-1]
表示word1[0:i-2]==word2[0:i-1]
,因此插入一个也能保证word1[0:i-1]==word2[0:i-1]
- 把
class Solution {
public:
int minDistance(string word1, string word2) {
int len1 = word1.length(), len2 = word2.length();
if (len1*len2 == 0) return len1 + len2;
vector<vector<int>> dist(len1 + 1, vector<int>(len2 + 1));
for (int i = 0; i < len1 + 1; ++i)
dist[i][0] = i;
for (int j = 0; j < len2 + 1; ++j)
dist[0][j] = j;
for (int i = 1; i < len1 + 1; ++i)
for (int j = 1; j < len2 + 1; ++j) {
int left = dist[i][j - 1];
int up = dist[i - 1][j];
int left_up = dist[i - 1][j - 1] - 1;
if (word1.at(i - 1) == word2.at(j - 1))
dist[i][j]=dist[i-1][j-1];
else
dist[i][j]=1 + min(dist[i-1][j-1], min(dist[i][j-1], dist[i-1][j]));
}
return dist[len1][len2];
}
};