题目一 583. 两个字符串的删除操作
给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 **相同所需的最小步数。
每步 可以删除任意一个字符串中的一个字符。
思路
-
dp[i][j]: 使以i-1结尾的word1和以j-1为结尾的word2相同所需的最小步数。
-
递推公式:
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
- 如果删除word1 的第i-1元素,
-
初始化
- dp[i][0]: word1的i个元素如何变成空串,即需要删除i个元素 = i
- dp[0][j]: word2的j个元素如何变成空串,即需要删除j个元素 = j
-
顺序遍历
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 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符 删除一个字符 替换一个字符
思路
- dp[i][j]: 以i-1结尾的word1子串和以j-1为结尾的word2子串变为相同需要的最少操作数
- 递推公式
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 - 取最小值
- 删除word1的i-1:
- 初始化:和上一道题相同
- 顺序遍历,取最后一个数字的值
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];
};