leetcode 72.编辑距离,官方答案的修改与分析

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

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

1.插入一个字符
2.删除一个字符
3.替换一个字符

示例 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')

题目的官方解答写的好像在两字符串插入字符的地方写错了,因此自己在这里写一下,顺便给自己一下动态规划的复习。

思路和算法

题目表述:我们可以对任意一个单词做三种操作(插入,删除,修改),设A,B为两个字符串通过一定次数推导已经很接近了。
本质上可视为3类操作:
(1)A=horse,B=hors。
实质可看作对B插入字母,与A删除字母e同效果。
(2)A=hors,B=horse。
实质可看作对A插入字母,与B删除字母e同效果。
(3)A=horse,B=horsa。
实质可看作修改a或者e。

若已知情况(1)中将A,B变为horse和hose所需要的操作次数为a;
已知情况(2)中将A,B变为hors和horse所需要的操作次数数为b;
已知情况(3)中将A,B变为horse和horsa所需要的操作次数数为c;
则A,B达到相同的次数则为min(a,b,c)。

接下来就是官方图解里所述的矩阵来进行分析了。
这里分析一下为什么要从两个单词开头进行比较——
道理也很简单= =,因为D[i][j]必须通过D[i][j-1],D[i-1][j] 和 D[i-1][j-1] 才能求出来。
而上哪能找到这三个同时都知道或者一开始就知道呢?
答:矩阵边缘和两边之夹角的位置,因为矩阵边缘的值一开始就确定了。
具体内容可以根据官方图解边看边分析。

代码

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n = word1.length();
        int m = word2.length();

        // 有一个字符串为空串
        if (n * m == 0) return n + m;

        // DP 数组
        int D[n + 1][m + 1];

        // 边界状态初始化
        for (int i = 0; i < n + 1; i++) {
            D[i][0] = i;
        }
        for (int j = 0; j < m + 1; j++) {
            D[0][j] = j;
        }

        // 计算所有 DP 值
        for (int i = 1; i < n + 1; i++) {
            for (int j = 1; j < m + 1; j++) {
                int left = D[i - 1][j] + 1;
                int down = D[i][j - 1] + 1;
                int left_down = D[i - 1][j - 1];
                if (word1[i - 1] != word2[j - 1]) left_down += 1;
                D[i][j] = min(left, min(down, left_down));

            }
        }
        return D[n][m];
    }
};

你可能感兴趣的:(leetcode 72.编辑距离,官方答案的修改与分析)