LeetCode 72.编辑距离

题目:

给你两个单词 word1word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。

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

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

思路:

  • 本题目可以使用动态规划来做,首先创建二维数组dp[i][j],表示当前情况word1的前i个字符word2的前j个字符的编辑距离。首先应该分情况讨论
  • 当两个字符串的最后一位都相同时,dp[i][j] = dp[i - 1][j - 1]
  • 当最后一位不相同时,那么最后一位就需要通过替换一步来保证相同,并且前面说过每个单词都可以插入,删除或者替换一个字符。因此可得状态转移方程dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;,也就是在dp[i - 1][j],dp[i][j - 1],dp[i - 1][j - 1]中寻找一个最小的编辑距离再加上一,这个1表示最后一个字符的替换步骤,最终得到当前字符的编辑距离

以下为代码+注释:

    public int minDistance(String word1, String word2) {
        // 动态规划
        int m = word1.length();
        int n = word2.length();
        int[][] dp = new int[m + 1][n + 1];
        // 首先将第一行的情况单独处理,也就是word1为空的情况,那么编辑距离就是当前情况word2的长度,也就是word1要添加的字符个数
        for(int i = 1; i <= n; i++){
            // 当前情况的字符长度
            dp[0][i] = i;
            // dp[0][i] = dp[0][i - 1] + 1;
        }
        // 第一列的单独情况是word2为空的时候,这个时候的编辑距离为当前情况word1的长度
        for(int i = 1; i <= m; i++){
            // 当前情况的字符长度
            dp[i][0] = i;
            // dp[i][0] = dp[i - 1][0] + 1;
        }
        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(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
                }
            }
        }
        // 返回最后一个值,也就是两个字符串从子问题中寻找的编辑距离最小情况的总和而得出的最小距离
        return dp[m][n];
    }

笔者也在不断学习,如有错误,欢迎指正!

你可能感兴趣的:(算法,字符串,java,算法,leetcode)