【前端er每日算法】动态规划--距离两题

113 阅读1分钟

题目一 583. 两个字符串的删除操作

给定两个单词 word1 和 word2 ,返回使得 word1 和  word2 **相同所需的最小步数

每步 可以删除任意一个字符串中的一个字符。

思路

  1. dp[i][j]: 使以i-1结尾的word1和以j-1为结尾的word2相同所需的最小步数。

  2. 递推公式:

    • word1[i-1] === word2[j-1]: dp[i][j] = dp[i-1][j-1]
    • word1[i-1] !== word2[j-1]
      • 如果删除word1 的第i-1元素,dp[i][j] = dp[i-1][j] + 1
      • 如果删除word2 的第j-1元素,dp[i][j] = dp[i][j-1] + 1
      • 如果同时删除word1的i-1元素和word2的j-1元素,dp[i][j] = dp[i-1][j-1] + 2
  3. 初始化

    • dp[i][0]: word1的i个元素如何变成空串,即需要删除i个元素 = i
    • dp[0][j]: word2的j个元素如何变成空串,即需要删除j个元素 = j
  4. 顺序遍历

var minDistance = function(word1, word2) {
    const len1 = word1.length;
    const len2 = word2.length;
    const dp = new Array(len1 + 1).fill(0).map(item => new Array(len2 + 1).fill(0));
    for (let i = 0; i <= len1; i++) {
        dp[i][0] = i;
    }
    for (let j = 0; j <= len2; j++) {
        dp[0][j] = j;
    }
    for (let i = 1; i <= len1; i++) {
        for (let j = 1; j <= len2; j++) {
            if (word1[i-1] === word2[j-1]) {
                dp[i][j] = dp[i-1][j-1]
            } else {
                dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]+1) + 1
            }
        }
    }
    return dp[len1][len2];
};

题目二 72. 编辑距离

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

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

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

思路

  1. dp[i][j]: 以i-1结尾的word1子串和以j-1为结尾的word2子串变为相同需要的最少操作数
  2. 递推公式
    • word1[i-1] === word2[j-1]: dp[i][j] = dp[i-1][j-1]
    • word1[i-1] !== word2[j-1]:
      • 删除word1的i-1: dp[i][j] = dp[i-1][j] + 1
      • 删除word2的j-1: dp[i][j] = dp[i][j-1] + 1
      • 替换word1的i-1变为和word2的j-1相等:dp[i][j] = dp[i-1][j-1] + 1
      • 取最小值
  3. 初始化:和上一道题相同
  4. 顺序遍历,取最后一个数字的值
var minDistance = function(word1, word2) {
    const len1 = word1.length;
    const len2 = word2.length;
    const dp = new Array(len1 + 1).fill(0).map(item => new Array(len2 + 1).fill(0));
    for (let i = 0; i <= len1; i++) {
        dp[i][0] = i;
    }
    for (let j = 0; j <= len2; j++) {
        dp[0][j] = j;
    }
    for (let i = 1; i <= len1; i++) {
        for (let j = 1; j <= len2; j++) {
            if (word1[i-1] === word2[j-1]) {
                dp[i][j] = dp[i-1][j-1];
            } else {
                dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1;
            }
        }
    }
    return dp[len1][len2];
};