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

思路

Edit Distance_第1张图片
pic1.png

STANFORD课件
https://web.stanford.edu/class/cs124/lec/med.pdf

Youtube视频
ttps://www.youtube.com/watch?v=Xxx0b7djCrs

复杂度
时间 O(NM) 空间 O(NM)

假设dp[i-1][j-1]表示一个长为i-1的字符串str1变为长为j-1的字符串str2的最短距离,如果我们此时想要把str1a这个字符串变成str2b这个字符串,我们有如下几种选择:

  • 替换: 在str1变成str2的步骤后,我们将str1a中的a替换为b,就得到str2b (如果a和b相等,就不用操作)
  • 增加: 在str1a变成str2的步骤后,我们再在末尾添加一个b,就得到str2b (str1a先根据已知距离变成str2,再加个b)
  • 删除: 在str1变成str2b的步骤后,对于str1a,我们将末尾的a删去,就得到str2b (str1a将a删去得到str1,而str1到str2b的编辑距离已知)

根据这三种操作,我们可以得到递推式

  • 若a和b相等:
dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i][j])
  • 若a和b不相等:
dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i][j]+1)

初始化:
因为将一个非空字符串变成空字符串的最小操作数是字母个数(全删),反之亦然,所以:

dp[0][j]=j, dp[i][0]=i

最后我们只要返回dp[m][n]即可,其中m是word1的长度,n是word2的长度

public class Solution {
    /*
     * @param word1: A string
     * @param word2: A string
     * @return: The minimum number of steps.
     */
    public int minDistance(String word1, String word2) {
        // write your code here
        //用DP,有三种情况
        int len1 = word1.length();
        int len2 = word2.length();
        
        int[][] distance = new int[len1 + 1][len2 + 1];
        
        //初始化,D[i][j]代表从word1的前i个字母 变形到 word2的前j个字母的距离
        for (int i = 1; i <= len1; i++) {
            distance[i][0] = i; //从word1的前i个字母 变形到word2的前0个字母 需要delete word1的前i个字母
        }
        
        for (int i = 1; i <= len2; i++) {
            distance[0][i] = i;//从word1的前0个字母 变形到word2的前i个字母 需要insert word1的前i个字母
        }
        
        //计算D[LEN1][LEN2]
        //必须从1开始,因为要计算D[i][j-1], D[i-1][j], D[i-1][j-1]
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                int insertDistance = distance[i][j - 1] + 1;
                int deleteDistance = distance[i - 1][j] + 1;
                int replaceDistance = distance[i - 1][j - 1] + 
                            (word1.charAt(i - 1) == word2.charAt(j - 1) ? 0 : 1);
                distance[i][j] = Math.min(insertDistance, Math.min(deleteDistance, replaceDistance));
             }
        }
        return distance[len1][len2];

    }
}

你可能感兴趣的:(Edit Distance)