72.Edit distance

September 17, 2017

72.Edit distance

Description

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

这道题要求求解两个字符串之间的编辑距离,也就是通过增删改,最少多少次才能把一个字符串转换为另一个字符串。

对于这种对字符串进行修改还要求极值的题目,一般使用动态规划来解决,需要解决的是动态规划过程中的状态方程。

依然用i,j两个变量代表当前需要判断的字符串长度,如果两个字符串i-1和j-1位置上的字符相同,则不需要进行修改,即dp[i][j]=dp[i-1][j-1]

如果不匹配,则需要考虑增删改三个操作分别的代价。

考虑增加,如果需要在前一个字符串第i位增加一个字符串,使其与第二个字符串相同,则需要的步数是:dp[i][j-1]+1,也就是取决于将长为i的字符串与长为j-1的字符串相匹配的修改次数+一次增加

考虑删除,如果需要删除第i位的字符使其与第二个字符串相同,则需要的步数是:dp[i-1][j]+1,与增加同理

考虑替代,如果需要将第i位的字符替代,使其与长为j的字符串相同,只需要考虑前i-1,j-1的修改次数+1即可

之后选出代价最小的方式即可。

状态方程梳理清楚后,就很容易写出代码了,需要注意的是在对第一行第一列进行初始化时,略有不同

代码如下:

class Solution {
    public int minDistance(String word1, String word2) {
        int [][]dp=new int[word1.length()+1][word2.length()+1];
        for(int i=0;i<=word1.length();++i){
            for(int j=0;j<= word2.length();++j){
                if(i==0||j==0){
                    dp[i][j]=i+j;
                }
                else{
                    if(word1.charAt(i-1)==word2.charAt(j-1))
                        dp[i][j]=dp[i-1][j-1];
                    else{
                        int replace=dp[i-1][j-1];
                        int delete=dp[i-1][j];
                        int insert=dp[i][j-1];
                        dp[i][j]=Math.min(Math.min(replace,delete),insert);
                        dp[i][j]++;
                    }
                }
            }
        }
        return dp[word1.length()][word2.length()];
    }
}