【Warrior刷题笔记】LC72. 编辑距离 【动态规划】详细注释简单易懂

题目

力扣72.编辑距离

解题思路

本题可以使用动态规划解决。
首先要理解编辑距离是指将word1转换成word2所使用的最少操作数。然后考虑这样一个问题,如果我们知道word1i-1个字符所构成的字符串到word2j-1个字符所构成的字符串的编辑距离是a(甭管怎么来的),那么word1i个字符与word2j个字符相同时word1i个字符所构成的字符串到word2j个字符串所构成的字符串的编辑距离也是a,因为新增字符都一样,无需做任何修改就能使word1i个字符所构成的字符串到word2j个字符串所构成的字符串相同;
word1i个字符与word2j个字符不同时,word1i个字符所构成的字符串到word2j个字符串所构成的字符串的编辑距离便是a+1,因为我们可以替换word1i个字符为word2j个字符使word1i个字符所构成的字符串到word2j个字符串所构成的字符串相同。
同理,如果我们知道word1i-1个字符所构成的字符串到word2j个字符所构成的字符串的编辑距离是b,那么word1i个字符所构成的字符串到word2j个字符串所构成的字符串的编辑距离就是b+1,因为我们可以删除word1i个字符使得word1i个字符所构成的字符串到word2j个字符串所构成的字符串相同;
如果我们知道word1i个字符所构成的字符串到word2j-1个字符所构成的字符串的编辑距离是c,那么word1i个字符所构成的字符串到word2前j个字符串所构成的字符串的编辑距离就是c+1,因为我们可以在word1i个字符后插入word2j个字符使得word1i个字符所构成的字符串到word2前j个字符串所构成的字符串相同。
理解了以上内容,我们定义二维数组dp[i][j]表示word1i个字符构成的字符串到word2j个字符构成的字符串的编辑距离,那么题目所求就是dp[m][n],其中mn分别为串一串二长度。
当字符word1[i-1]==word2[j-1]时(下标从零开始),显然dp[i][j]=dp[i-1][j-1];否则,

dp[i][j] = min(
        dp[i-1][j-1]/*对应替换操作*/,
        dp[i][j-1]/*对应插入操作*/, 
        dp[i-1][j]/*对应删除操作*/
        ) + 1

以上推导过程没有考虑dp[i-1][j-1]dp[i][j-1]dp[i-1][j]是怎么来的,也即,没有考虑动态规划的边界条件。考虑当word1为空,我们就只能通过插入操作得到word2,那么很显然有dp[0][j]=j (0≤j≤n),同理,考虑当word2为空,我们就只能通过删除操作得到word2,那么很显然有dp[i][0]=i (0≤i≤m)

代码

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();//计算两串长
        if(m*n==0) return n + m;//若其中一个为0,则返回另一个的长度
        int dp[m+1][n+1];//辅助数组
        for(int i = 0; i <= n; ++i) dp[0][i] = i;//边界条件
        for(int i = 0; i <= m; ++i) dp[i][0] = i;//边界条件
        for(int i = 1; i <= m; ++i){
            for(int j = 1; j <= n; ++j){
                if(word1[i-1]==word2[j-1]) dp[i][j] = dp[i-1][j-1];//如果word1第i个字符与word2第j个字符相同
                else{//如果word1第i个字符与word2第j个字符不同同
                    dp[i][j] = min(min(dp[i-1][j-1], dp[i][j-1]), dp[i-1][j]) + 1;
                }
            }
        }
        return dp[m][n];
    }
};

复杂度分析

时间复杂度: O(m*n)m,n分别为两串串长,主要是遍历填表的时间消耗。
空间复杂度: O(m*n)。辅助数组的空间消耗。

你可能感兴趣的:(leetcode刷题笔记,动态规划,算法,c++)