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

 

提示:

  • 0 <= word1.length, word2.length <= 500
  • word1word2 由小写英文字母组成
Related Topics
  • 字符串
  • 动态规划

  • 👍 2443
  • 👎 0
  • 【动态规划】java 编辑距离

    直接上图

    动态规划的思想不做过多描述了。主要分析下这个过程。

    以中间一步的标号35的格子的 ABCDE需要转换成BBAC为例

    如下情况

    1. 可以由已知的ABCDBBAC的过程之前执行一次删除末位的字母E操作 (对应删除)
    2. 可以由已知的ABCDEBBA的过程之后再执行一次插入字母C的操作来达到 (对应插入)
    3. ABCDBBA的操作再执行一次修改操作,把E改为C来达到,如果字母相同则不需要修改 (对应修改)

    代码

    class Solution {
        public int minDistance(String word1, String word2) {
            int lenght1 = word1.length();
            int lenght2 = word2.length();
            int[][] dp = new int[lenght1+1][lenght2+1];
            for (int i = 0; i <= lenght1 || i <= lenght2; i++) {
                if (i <= lenght2){
                    dp[0][i] = i;
                }
                if (i <= lenght1){
                    dp[i][0] = i;
                }
            }
            for (int row = 1; row <= lenght1; row++) {
                for (int col = 1; col <= lenght2; col++) {
                    dp[row][col] = Math.min(
                            dp[row-1][col-1] + (word2.charAt(col-1) == word1.charAt(row-1)?0:1) ,
                            Math.min(dp[row][col-1],dp[row-1][col]) + 1
                    );
                }
            }
            return dp[lenght1][lenght2];
        }
    }

    思考题

    当我们计算标号35的格子的时候,为什么不能从右上角的标号30的格子推导而来呢?
    或者说可以从标号23和18的关系来再看一下