LeetCode 72. Edit Distance 编辑距离 (C++/Java)

题目:

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

分析:

给定两个单词,求word1转换到word2需要的最少步骤,转换的操作有三种,分别是插入一个字符,删除一个字符,替换一个字符。

d(word1, word2)用来求两个单词转换的需要的最小步数,那么如果当两个单词的最后一个字符是相同的,则d(word1, word2) = d(word1', word2')其word1'和word2'是分别去掉最后一个字符的单词。

如果最后两个字符不相同时,我们就需要操作来进行转换,一种是在word1后增加一个字符,是其最后一个字符和word2的最后一个字符相同,一种是删去word1的最后一个字符,一种是将word1的最后一个字符转换成word2的最后一个字符,那么此时最小的步数就是前三个操作的最小值加上1.

可能有同学会问为什么不在word2上进行操作,实际上操作转换这一步是有5个子问题的,但实际上在word1后增加一个字符和word2最后字符相同,相当于在word2后删除字符;删去word1的字符相当于在word2后增加一个字符和word1最后字符相同;而转换操作明显是一样的,所以就合并成为了三个子问题。

当递归执行到其中一个串为空串时,则加上另一个串的长度即可,相当于删去所有的字符。

程序:

C++

class Solution {
public:
    int minDistance(string word1, string word2) {
        int l1 = word1.length();
        int l2 = word2.length();
        dp = vector<vector<int>>(l1+1, vector<int>(l2+1, -1));
        return minDistance(word1, word2, l1, l2);
    }
private:
    vector<vector<int>> dp;
    int minDistance(string& word1, string& word2, int l1, int l2){
        if(l1 == 0)
            return l2;
        if(l2 == 0)
            return l1;
        if(dp[l1][l2] >= 0)
            return dp[l1][l2];
        int res = 0;
        if(word1[l1-1] == word2[l2-1]){
            res = minDistance(word1, word2, l1-1, l2-1);
            dp[l1][l2] = res;
            return res;
        }
        res = min(minDistance(word1, word2, l1-1, l2), 
                    min(minDistance(word1, word2, l1, l2-1),
                    minDistance(word1, word2, l1-1, l2-1))) + 1;
        dp[l1][l2] = res;
        return res;
    }
};

Java

class Solution {
    public int minDistance(String word1, String word2) {
        int l1 = word1.length();
        int l2 = word2.length();
        dp = new int[l1+1][l2+1];
        for(int i = 0; i < dp.length; ++i){
            for(int j = 0; j < dp[i].length; ++j){
                dp[i][j] = -1;
            }
        }
        return minDistance(word1, word2, l1, l2);
    }
    private int minDistance(String word1, String word2, int l1, int l2){
        if(l1 == 0) return l2;
        if(l2 == 0) return l1;
        if(dp[l1][l2] >= 0)
            return dp[l1][l2];
        int res = 0;
        if(word1.charAt(l1-1) == word2.charAt(l2-1)){
            res = minDistance(word1, word2, l1-1, l2-1);
        }else{
            res = Math.min(minDistance(word1, word2, l1-1, l2),
                 Math.min(minDistance(word1, word2, l1, l2-1),
                    minDistance(word1, word2, l1-1, l2-1))) + 1;
        }
        dp[l1][l2] = res;
        return res;
    }
    private int[][] dp;
}

 

posted @ 2020-02-26 15:05  silentteller  阅读(388)  评论(0编辑  收藏  举报