leecode72. 编辑距离

72. 编辑距离

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

插入一个字符
删除一个字符
替换一个字符

示例 1:

输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')

示例 2:

输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

思路:由题可知存在最优子结构和重复子问题,因此可以使用动态规划的思路来解决此题,我们使用dp[i][j]来记录word1的前i个字符与word2的前j个字符所使用的最小操作,其操作可以分为两种。

  • 如果word1的第i个字符和word2的第j个字符相等,那么就不需要执行任何操作,因此就可以看成word的前i-1个操作和j-1的操作,即dp[i][j]=d[i-1][j-1]

  • 如果不相等,可以通过插入、删除、替换的方式来解决,具体如下

    • 首先是插入,我们对于word1末尾插入与word2相同的字符,那么此时i的长度加1,因此dp[i][j]=d[i][j-1]+1
    • 然后是删除,选择删除操作删掉word1最末尾的数,删除后两种最末尾数不一定相等,此时我们后续的操作为比较word[i-1]和word[j]字符串即可dp[i][j]=dp[i-1][j]+1
    • 最后为替换,即将word1末尾的字符,替换成和word2末尾字符相等即可,那么在相等后dp[i][j]=d[i-1][j-1]+1

    对于以上三种操作,我们只需要选取操作其中最小的即可dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;

代码如下所示:

class Solution {
    public int minDistance(String word1, String word2) {
        int lengthA = word1.length();
        int lengthB = word2.length();
        if (lengthA * lengthB == 0) {
            return lengthA + lengthB;
        }
        int[][] dp = new int[lengthA+1][lengthB+1];
        for(int i=0;i<=lengthA;i++){
            dp[i][0] = i;
        }
        for(int i=0;i<=lengthB;i++){
            dp[0][i]=i;
        }
        for(int i=1;i<=lengthA;i++){
            for(int j=1;j<=lengthB;j++){
                if(word1.charAt(i-1)==word2.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1];
                }else{
                    dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
                }
            }
        }
        return dp[lengthA][lengthB];
    }
}
posted @ 2022-07-20 10:40  zqy123  阅读(25)  评论(0编辑  收藏  举报