算法学习之动态规划(leetcode 72. Edit Distance)

0x01题目
72. Edit Distance
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

You have the following 3 operations permitted on a word:

a) Insert a character
b) Delete a character
c) Replace a character
0x02解析

写在前面:自己在做这个题目的时候,没有考虑到动态规划的思想,只是想当然的去直观地解决问题,最后发现无法直观解决。在动态规划中最重要的一个思想是建模,建立一个概念。
具体解析:定义dp[i][j],其含义为word1[0 ... i-1]转化成word2[0 ... j-1]的步数,其值分为两类,第一种是边界值,第二种是一般值。
边界值的获取过程如下,如dp[0][j]代表的含义为空字符串""转化成word2[0 ... j-1]的步数,显然为j;同理,dp[i][0]代表的含义为word1[0 ... i-1]转化成空字符串""的步数,显然为i
一般值的获取过程如下,假设我们已经得到了dp[i-1][j-1],如何得到dp[i][j]呢?分如下情况讨论。
(1)当word1[i-1] == word2[j-1]时。此种情况下,只需要将word1[0 ... i-2]转化为word2[0 ... j-2]即可(最后一个字符相同),因此dp[i][j] = dp[i-1][j-1]
(2)当word1[i-1] != word2[j-1]时。此种情况下,根据题中给出的条件,分为以下三种情况(核心都是将word1转化成word2

  1. 在word1中插入字符
    首先将word1[0 ... i-1]转化为word2[0 ... j-2]dp[i][j-1]),然后在word1[0 ... i-1]插入字符为word2[j-1],即word1[0 ... i-1] => word2[0 ... j-2] 且插入 word2[j-1]dp[i][j] = dp[i][j-1] + 1
  2. 在word1中删除字符
    首先将word1[0 ... i-2]转化为word2[0 ... j-1]dp[i-1][j]),然后将字符word1[i-1]删除,即word1[0 ... i-2]=>word2[0 ... j-1] 且删除 word1[i-1]dp[i][j] = dp[i-1][j] + 1
  3. 在word1中替换字符
    首先将word1[0 ... i-2]转化为word2[0 ... j-2]dp[i-1][j-1]),然后将用word2[j-1]替换字符word1[i-1],即word1[0 ... i-2] => word2[0 ... j-2] 且 word1[i-1] => word2[j-1]dp[i][j] = dp[i-1][j-1] + 1
0x03代码

根据以上总结,可以得出的代码如下

public class Solution {
    public int minDistance(String word1, String word2) {
        if(word1 == null || word2 == null) return 0;

        int len1 = word1.length(), len2 = word2.length();
        int[][] dp = new int[len1 + 1][len2 + 1];
        dp[0][0] = 0;
        for(int i = 1; i <= len1; i++){
            dp[i][0] = i;
        }
        for(int j = 1; j <= len2; j++){
            dp[0][j] = j;
        }

        for(int x = 1; x <= len1; x++){
            for(int y = 1; y <= len2; y++){
                if(word1.charAt(x - 1) == word2.charAt(y - 1)){
                    dp[x][y] = dp[x - 1][y - 1];
                }
                else{
                    dp[x][y] = Math.min(Math.min(dp[x - 1][y - 1] + 1, dp[x - 1][y] + 1), dp[x][y - 1] + 1);
                }
            }
        }

        return dp[len1][len2];
    }
}

参考 https://discuss.leetcode.com/topic/17639/20ms-detailed-explained-c-solutions-o-n-space

你可能感兴趣的:(leetcode算法学习,动态规划,leetcode,算法)