LEETCODE 72.编辑距离题解

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符

72.编辑距离

示例 1:
输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
示例 2:
输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

题解

一道非常典型的DP问题,看如何进行状态转移

我们首先定义dp数组的含义:dp[i][j]表示word1[0…i]到word2[0…j]的最少编辑次数。

其次,确定初始状态,对于word2长度为0的情况,word1的编辑次数便是word1的长度。即dp[i][0] = i
对于word1长度为0的情况,word2的编辑次数便是word2的长度。即dp[0][i] = i

我们可以注意到这两句话里主体的不同,在接下来的分析中,我们便能确定谁才是我们需要操作的主体并定位dp的位置

假设我们已经到了(i,j),那么我们就已经已知(i-1,j-1),(i,j-1),(i-1,j)的最少编辑次数了。
在这里插入图片描述
当我们继续判断第i,j位时,有两种情况:

word1[i] == word2[j]

  • 这种情况下,显然dp[i][j] = dp[i-1][j-1]

word1[i] != word2[j]

在这种情况下,我们有三种选择:

  • 删除:删除掉word1的一个字符,那么操作次数就是dp[i-1][j] + 1

  • 为什么是dp[i-1][j]而不是dp[i[[j-1]呢?请看上一个注释,注意操作主体的不同

  • 添加:请注意,word1添加一个字符,其实相当于word2删除一个字符,即dp[i][j-1] + 1

  • 其实删除操作也同理,那么就会出现两对相同的操作(min(f[i - 1][j], f[i][j - 1]) + 1),这里删除和添加只取了一对

  • 替换:对于替换操作,即同时取dp[i-1][j-1] + 1

由此,给出js AC代码:

/**
 * @param {string} word1
 * @param {string} word2
 * @return {number}
 */
var minDistance = function(word1, word2) {
    if(!word1 && !word2) return 0
    //dp数组含义:dp[i][j]:需要的最少操作数
    let dp = Array(word2.length+1).fill(0).map(()=>Array(word1.length+1).fill(0))
    // let dp = Array(word2.length+1).fill(Array(word1.length+1).fill(0))
    //初始状态
    for(let i=0;i<=word2.length;i++){
        dp[i][0] = i
    }
    for(let i=0;i<=word1.length;i++){
        dp[0][i] = i
    }

    for(let i=1;i<=word2.length;i++){
        for(let j=1;j<=word1.length;j++){
            if(word2[i-1] == word1[j-1]){
                dp[i][j] = dp[i-1][j-1]
            }else{
                const tmp = [dp[i-1][j-1],dp[i-1][j],dp[i][j-1]]
                dp[i][j] = 1 + Math.min(...tmp)
            }
        }
    }

    return dp[word2.length][word1.length]
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值