LeetCode: 72. Edit Distance(Week 9)

72. 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') 	
    
  • 思路解析

    • 这道题是一道动态规划的题,需要将一个字符串word1经过adddeletereplace三种操作变换成另一个字符串word2,求最小的编辑距离.
    • 解题思路:假设word1=[123...n] ,word2=[123...m],要求使得word1转换成word2。对于这个问题,我们将其分解为子问题求解。
      • 定义dis[i][j]
        • 表示word1' = [1..i]转换成word2' = [1...j]的编辑距离(i代表word1i个字符,j代表word2j个字符)
        • 因此word1word2的编辑距离为dis[n][m]
      • 求解word1word2的编辑距离,我们可以求取word1的前i个字符(0 < i < n)到word2的前j个字符(0 < j < m)的编辑距离dis[i][j]。当然每个dis[i][j]都基于之前的计算。
      • 步骤
        • 初始化

          • dis[i, 0] = i
          • dis[0, j] = j
        • 递推关系核心

          d i s [ i ] [ j ] = m i n { d i s [ i ] [ j 1 ] + 1 d i s [ i 1 ] [ j ] + 1 d i s [ i 1 ] [ j 1 ] + ( w o r d 1 [ i 1 ] = = w o r d 2 [ j 1 ] ? 0 : 1 ) ) dis[i][j] = min \begin{cases} dis[i][j-1] + 1\\ dis[i-1][j] + 1\\ dis[i-1][j-1] + (word1[i-1] == word2[j-1] ? 0 : 1))\\ \end{cases}
          其中三个操作的表示

          • insert: dis[i, j] = dis[i][j-1] + 1
          • delete: dis[i, j] = dis[i-1][j] + 1
          • replace or no opdis[i, j] = dis[i-1][j-1] + (word1[i-1] == word2[j-1] ? 0 : 1)

          对于每dis[i][j],我们选取最小编辑距离

      • 最后得到的dis[n][m]就是word1word2的编辑距离
  • 实现代码

    class Solution {
    public:
        int minDistance(string word1, string word2) {
    		int m = word1.size();
    		int n = word2.size();
    		int dis[m+1][n+1] = {0};
    
    		for (int i = 0; i <= m; ++i)
    			dis[i][0] = i;
    
    		for (int j = 0;j <= n; ++j)
    			dis[0][j] = j;
    
    		// m or n equal 0
    		if (!m && !n)
    			return max(m, n);
    
    		// insert: 	dis[i, j] = dis[i][j-1] + 1	
    		// delete:	dis[i, j] = dis[i-1][j] + 1
    		// replace or no op:	dis[i, j] = dis[i-1][j-1] + (word1[i-1] == word2[j-1] ? 0 : 1)
    
    		for (int i = 1; i <= m; ++i) {			
    			for (int j = 1; j <= n; ++j) {
    				dis[i][j] = min(dis[i][j-1] + 1,
    					min(dis[i-1][j] + 1, dis[i-1][j-1] + (word1[i-1] == word2[j-1] ? 0 : 1)));
    			}
    		}
    		return dis[m][n];
        }
    };
    
  • 参考链接 - pdf

猜你喜欢

转载自blog.csdn.net/lllllyt/article/details/83547904