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

来源:互联网 发布:mysql variables 修改 编辑:程序博客网 时间:2024/06/05 03:51
0x01题目
72. Edit DistanceGiven 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 characterb) Delete a characterc) 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

0 0
原创粉丝点击