72. 编辑距离

题目:给你两个单词word1和word2,计算将word1转成word2所需要的的最少操作数。你可以对一个单词进行如下三种操作:

  1. 插入一个字符
  2. 删除一个字符
  3. 替换一个字符

思路:两个单词总共有6种操作,但是其中3种操作是等价的:

  1. 单词1插入一个字符(等价于单词2删除一个字符)
  2. 单词2插入一个字符(等价于单词1删除一个字符)
  3. 单词1替换一个字符(等价于单词2替换一个字符)

动态规划,用D[i][j]表示单词1的前i个字符和单词2的前j个字符之间的编辑距离。

  • D[i][j-1]: 对于单词2的第j个字符,在单词1末尾添加一个相同的字符,那么D[i][j]最小可以为D[i][j-1]+1
  • D[i-1][j]: 对于单词1的第i个字符,在单词2末尾添加一个相同的字符,那么D[i][j]最小可以为D[i-1][j]+1
  • D[i-1][j-1]: 若单词1的第i个字符和单词2的第j个字符相等,则D[i][j]最小可以为D[i-1][j-1];否则修改单词1的第i个字符为单词2的第j个字符,则 D[i][j]最小可以为D[i-1][j-1]+1
int minDistance(string word1, string word2){
    int m = word1.length();
    int n = word2.length();
    //有一个字符串为空
    if(m*n==0) return n+m;
    //dp[i][j]表示word1的前i个字符和word2的前j个字符之间的编辑距离
    int dp[m+1][n+1];
    for(int i=0; i<=m; i++){
        dp[i][0]=i;
    }
    for(int j=0; j<=n; j++){
        dp[0][j]=j;
    }
    for(int i=1; i<=m; i++){
        for(int j=1; j<=n; j++){
            dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1);
            if(word1[i-1] == word2[j-1]){  //word1的第i个字符和word2的第j个字符
                dp[i][j] = min(dp[i][j], dp[i-1][j-1]);
            }else{
                dp[i][j] = min(dp[i][j], dp[i-1][j-1]+1);
            }
        }
    }
    return dp[m][n];
}

你可能感兴趣的:(72. 编辑距离)