LeetCode 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:

    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')
    

Reference Answer

思路分析

思路

  • 用一个 dp 数组维护两个字符串的前缀编辑距离

  • DP 定义

    • word[0:i] := word 长度为 i 的 前缀子串
    • 定义 dp[i][j] := 将 word1[0:i] 转换为 word2[0:j] 的操作数
  • 初始化

    dp[i][0] = i  // 每次从 word1 删除一个字符
    dp[0][j] = j  // 每次向 word1 插入一个字符
    
  • 递推公式

    • word1[i] == word2[j]
      

      dp[i][j] = dp[i-1][j-1]
      
    • word1[i] != word2[j]
      

      时,有三种更新方式,取最小

      // word[1:i] 表示 word 长度为 i 的前缀子串
      dp[i][j] = min({ dp[i-1][j]   + 1 ,     // 将 word1[1:i-1] 转换为 word2[1:j] 的操作数 + 删除 word1[i] 的操作数(1)
                       dp[i][j-1]   + 1 ,     // 将 word1[0:i] 转换为 word2[0:j-1] 的操作数 + 将 word2[j] 插入到 word1[0:i] 之后的操作数(1)
                       dp[i-1][j-1] + 1 })    // 将 word1[0:i-1] 转换为 word2[0:j-1] 的操作数 + 将 word1[i] 替换为 word2[j] 的操作数(1)
      

Code

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.length();
        int n = word2.length();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
        for(int i = 0; i <= m; ++i){
            dp[i][0] = i;
        }
        for(int j = 0; j <= n; ++j){
            dp[0][j] = j;
        }
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
                if(word1[i-1] == word2[j-1]){
                    dp[i][j] = dp[i-1][j-1];
                }
                else{
                    dp[i][j] = min({dp[i-1][j], dp[i][j-1], dp[i-1][j-1]}) + 1;
                }
            }
        }
        return dp[m][n];
        
    }
};
        

Note

  • 这道题难在思想上。

你可能感兴趣的:(LeetCode 72. Edit Distance (编辑距离))