leetcode72题编辑距离-动态规划

题目

给定两个单词 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')

详解和代码如下:


import org.springframework.util.StringUtils;

/***
 *
 * 给定两个单词 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')
 *
 * 动态规划实现:其实就是把两个字符串从头到尾两个for循环计算word1[0-i]和word2[0-j]相匹配时的最小操作数
 * 因为有最优子特性,所以可以从下往上来递推
 */

public class 编辑距离 {

    public static int minDistance(String word1, String word2) {
        if (StringUtils.isEmpty(word1)) {
            return word2.toCharArray().length;
        }
        if (StringUtils.isEmpty(word2)) {
            return word1.toCharArray().length;
        }
        int m = word1.length();
        int n = word2.length();

        //定义dp数组,dp[i][j] 表示word1的第i为和word2的j位相同时需要操作几次,
        // 注意此时dp[0-i][0-j]之间的位,两个字符串已经相同了,这是关键
        //所以最后的int[m][n]就是结果了,就是两个word完全相同了
        int[][] dp = new int[m + 1][n + 1];
        //初始化边界条件
        for (int i = 1; i <= m; i++) {
            dp[i][0] = dp[i - 1][0] + 1;
        }
        for (int j = 1; j <= n; j++) {
            dp[0][j] = dp[0][j-1] + 1;
        }

        //定义dp方程:前面dp数组已经定义了,dp方程就比较简单了,
        // 当word1[i]==word[j]时:dp[i][j] = dp[i-1][j-1] 此时不需要任何操作
        // 当word1[i]!=word[j]时:就需要操作了,怎么操作呢?有三种:
        // 如果删除,删除代表word[i]位需要删除掉 比如:word1:abce  word2 abc空 此时 i=3,j=2时需要删除e
        // 删除的情况 dp[i][j] = dp[i-1][j]+1, 表示当前word1[i]与word2[j]是不匹配的,那我去找下word1[i-1]与word2[j]匹配的情况,如果该情况下最小,那就删除当前的word1[i]
        // 更新的情况:dp[i][j] = dp[i-1][j-1]+1  表示第i个字符需要替换
        // 插入的情况:dp[i][j] = dp[i][j-1]+1  表示当前word1[i]与word2[j]是不匹配的,那我就去看看dp[i][j-1]匹配的时候的值然后新增一个数word[i+1] = word[j]就行了
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i - 1][j - 1], dp[i][j - 1])) + 1;
                }
            }
        }

        return dp[m][n];
    }
    public static void main(String[] args) {
        System.out.println(minDistance("plasma","altruism"));
    }
}
发布了23 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq1076472549/article/details/104004922
今日推荐