【DP】LeetCode 72. 编辑距离

题目链接

72. 编辑距离

思路

分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律

在数组的动态规划问题中,一般 dp[i] 都是表示以 nums[i] 为结尾的状态;dp[i][j] 分别表示 以 nums1[i]nums2[j] 为结尾的状态,以此类推

字符串也是个数组,是字符数组

参考题解:自底向上和自顶向下

对“dp[i-1][j-1] 表示替换操作,dp[i-1][j] 表示删除操作,dp[i][j-1] 表示插入操作。”的补充理解:

以 word1 为 "horse",word2 为 "ros",且 dp[5][3] 为例,即要将 word1的前 5 个字符转换为 word2的前 3 个字符,也就是将 horse 转换为 ros,因此有:

(1) dp[i-1][j-1],即先将 word1 的前 4 个字符 hors 转换为 word2 的前 2 个字符 ro,然后将第五个字符 word1[4](因为下标基数以 0 开始) 由 e 替换为 s(即替换为 word2 的第三个字符,word2[2])

(2) dp[i][j-1],即先将 word1 的前 5 个字符 horse 转换为 word2 的前 2 个字符 ro,然后在末尾补充一个 s,即插入操作

(3) dp[i-1][j],即先将 word1 的前 4 个字符 hors 转换为 word2 的前 3 个字符 ros,然后删除 word1 的第 5 个字符

代码

dp数组版

class Solution {
    public int minDistance(String word1, String word2) {
        // dp[i][j] 表示 word1 前 i 个字符转变到 word2 前 j 个字符所需的操作次数
        // 增:dp[i][j] = dp[i][j - 1] + 1
        // 删:dp[i][j] = dp[i - 1][j] + 1
        // 改:dp[i][j] = dp[i - 1][j - 1] + 1
        int n1 = word1.length();
        int n2 = word2.length();
        int[][] dp = new int[n1 + 1][n2 + 1];

        // 第一行
        for(int j = 1; j <= n2; j++){
            dp[0][j] = dp[0][j - 1] + 1;
        }
        // 第一列
        for(int i = 1; i <= n1; i++){
            dp[i][0] = dp[i - 1][0] + 1;
        }

        for(int i = 1; i <= n1; i++){
            for(int j = 1; j <= n2; 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 - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;
                }
            }
        }

        return dp[n1][n2];
    }
}
posted @ 2023-04-18 16:57  Frodo1124  阅读(13)  评论(0编辑  收藏  举报