DP经典题:编辑距离

leetcode72.编辑距离

题目:

给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

  • 插入一个字符
  • 删除一个字符
  • 替换一个字符

提示:

  • 0 <= word1.length, word2.length <= 500
  • word1word2 由小写英文字母组成

 思路:

使用动态规划:状态表示f(i,j)表示将word1(1\sim i)变成word2(1\sim j)所需要的最少操作次数。因为分别有插入、删除、修改三种操作方式。所以共有三种状态转移方程:

  • word1插入一个字符变成word2f(i,j)=f(i,j-1)+1
  • word2删除一个字符变成word2f(i,j)=f(i-1,j)+1
  • word1替换一个字符变成word2f(i,j)=f(i-1,j-1)+0/1

 代码(Java):

class Solution {
    public int minDistance(String w1, String w2) {
        w1 = " " + w1;
        w2 = " " + w2;
        int n = w1.length(),m = w2.length();
        int[][] f = new int[n+1][m+1];
        for(int i = 0;i <= n;i++)
            f[i][0] = i;
        for(int i = 0;i <= m;i++) 
            f[0][i] = i;
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= m;j++) {
                f[i][j] = Math.min(f[i][j-1],f[i-1][j]) + 1;
                f[i][j] = Math.min(f[i][j],f[i-1][j-1] + (w1.charAt(i-1) == w2.charAt(j-1) ? 0 : 1));
            }
        }
        return f[n][m];
    }
}

编辑距离变形题(简化):leetcode583.两个字符串的删除操作

题目

给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。

提示:

  1. 给定单词的长度不超过500。
  2. 给定单词中的字符只含有小写字母。

思路:

解法1:当作是编辑距离的简化版。这里是只有删除操作,将a(1\sim i)变成b(1\sim j)有两种操作:一是删除a_i变成b(1\sim j),那么f(i,j)=f(i-1,j)+1;二是删除b_j变成b(1\sim j-1),那么f(i,j)=f(i,j-1)+1。另外还有特殊情况,就是a_i==b_j,那么f(i,j)=f(i-1,j-1)

代码(Java):

class Solution {
    public int minDistance(String w1, String w2) {
        int n = w1.length(), m = w2.length();
        w1 = " " + w1;
        w2 = " " + w2;
        int[][] f = new int[n+1][m+1];
        for(int i = 0;i <= n;i++) {
            f[i][0] = i;
        }
        for(int j = 0;j <= m;j++) {
            f[0][j] = j;
        }
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= m;j++) {
                f[i][j] = Math.min(f[i-1][j],f[i][j-1]) + 1;
                if(w1.charAt(i) == w2.charAt(j)) {
                    f[i][j] = Math.min(f[i][j],f[i-1][j-1]);
                }
            }
        }
        return f[n][m];
    }
}

解法2:这题是对两个字符串分别删除一些元素使得两个字符串相同,所以可以联想到两个字符串的最长公共子序列问题。求出两个字符串的最长公共子序列的长度k,那么这题的解就是len(a)+len(b)-2*k

class Solution {
    public int minDistance(String w1, String w2) {
        int n = w1.length(),m = w2.length();
        w1 = " " + w1;
        w2 = " " + w2;
        int[][] f = new int[n+1][m+1];
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= m;j++) {
                f[i][j] = Math.max(f[i-1][j],f[i][j-1]);
                if(w1.charAt(i) == w2.charAt(j)) {
                    f[i][j] = Math.max(f[i][j],f[i-1][j-1] + 1);
                }
            }
        }
        return n + m - 2 * f[n][m];
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值