LeetCode 72 题:编辑距离

动态规划套路
把问题层层剖析,当它变成一个字符的时候,比如 ‘a’ 和 ‘b’,这时候是不是只需要变换一次就可以实现转换了,那如果‘ab’ 和 ‘ba’ 呢,不就是在‘a’ 跟 ‘b’的基础上再进行一次变换吗(看问题需要看到点上才能解决,不能按平常思维进行顺序分析)

问题解决,既然是动态规划,那自然就有两种方法

一种是递归法,也就是自顶向下,层层解析,定义出口,最终得出答案,不过递归的缺点就是重复计算,以及栈溢出问题,不建议使用。

另一种就是 dp 数组了,定义一个二维的 dp 数组保存最少的步数,再通过前一次的步数来求出下一次的步数(动态规划最最重要的要点),首先是 dp[i][j],代表了从 str1 的第 i 个位置到 str2 的第 j 个位置的最少步数。

既然是动态规划,那自然少不了 base case, 状态转移,只要找到状态转移自然能解

      //base  case
     for (int i = 0; i < dp.length; i++) {
            dp[i][0] = i;//str1的第 i 位走到 str2的第 0 位i
        }
        for (int j = 0; j < dp[0].length; j++) {
            dp[0][j] = j;
        }
//状态转移
//也就是从   左,  上 ,   左上    这三个位置找到最小的
//如果刚好 str1[i] == str2[j] 的时候呢,就不需要做变换,也就是不需要加一

dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])) + 1;
                //条件,如果该位置两个字符相等,就不用加一
                if (str1.charAt(i - 1) == str2.charAt(j - 1)){
                    dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1]);
                }
public int minDistance(String str1, String str2){
    int m = str1.length();
    int n = str2.length();
    if (m * n == 0) return m + n;
    //初始化 dp 数组
    int[][] dp = new int[m + 1][n + 1];
    for (int i = 0; i < dp.length; i++) {
        dp[i][0] = i;//str1的第 i 位走到 str2的第 0 位i
    }
    for (int j = 0; j < dp[0].length; j++) {
        dp[0][j] = j;
    }
    //状态转移
    for (int i = 1; i < dp.length; i++) {
        for (int j = 1; j < dp[0].length; j++) {
            dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])) + 1;
            //条件,如果该位置两个字符相等,就不用加一
            if (str1.charAt(i - 1) == str2.charAt(j - 1)){
                dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1]);
            }
        }
    }
    return dp[m][n];
}

总结:是一道困难题,也是动态规划中非常经典的题目,建议理解思想,慢慢吸收。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容