【LeetCode】72. Edit Distance(C++)

地址: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:

  1. Insert a character
  2. Delete a character
  3. 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]
  • 否则,我们有下面几种方法修改
    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
    • 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];
	}
};

猜你喜欢

转载自blog.csdn.net/Ethan95/article/details/85342022