72. 编辑距离

题目


给出两个单词 word1 和 word2,找出将 word1 转换成 word2 所使用的最少的步骤数 (每个操作记为一步)。

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

a) 插入一个字符
b) 删除一个字符
c) 替换一个字符

思路

动态规划的题目

  1. 递归
dp[i][j]:表示word1[1..i]编辑成为word2[1..j]所需要的操作数
d("abbc","acc") = d("abb","ac") 
                = 1 + min(d("ab","a"),  // 替换
                         d("abb","a"),  //添加
                         d("ab",“ac”))     //删除

上述一个递归过程:

  1. 如果字符串最后一个相等,两个字符串-1
  2. 如果不相等:
    2.1 替换操作:需要求得d(两个字符串-1)的最小距离
    2.2 添加操作:添加之前的状态就是,d(当前字符串编辑成为模式串-1)
    2.3 删除操作:删除之前的状态就是,d(当前字符串删掉一个后编辑成为模式串)

2里的每个操作+1

  1. 动态规划
    递推:d(i, j) 表示把 str1 前 i 个字符编辑成 str2 前 j 个字符所需要的最小 edit distance

     d(2, 1)     = 1 + d(1, 1)
    

edit("ab", "a") = 1 + edit("a", "a") <- delete "b" from str1

    d(1, 2)     = 1 + d(1, 1)

edit("a", "ab") = 1 + edit("a", "a") <- insert "b" into str1

    d(2, 2)     = 1 + d(1, 1)

edit("ab", "ac") = 1 + edit("a", "a") <- replace "b" with "c" in str1

代码

    public int minDistance(String word1, String word2) {
        int m = word1.length();
        int n = word2.length();
        int[][] dp = new int[m + 1][n + 1];
        //init
        //str2 == ""
        for (int i = 0; i <= m; i++) {
            dp[i][0] = i;
        }
        //str1 == "" 
        for (int j = 0; j <= n; j++) {
            dp[0][j] = 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 - 1], Math.min(dp[i-1][j],dp[i][j-1])) + 1;
                }
            }
        }
        return dp[m][n];
    }

你可能感兴趣的:(72. 编辑距离)