1.力扣583. 两个字符串的删除操作
1.1 题目描述
题目描述:
给定两个单词word1和word2,找到使得word1和word2相同所需要的的最小步数,每步可以删除任意一个字符串的一个字符。
例:
输入:“sea”,“eat”
输出:2
解释:第一步将"sea"变为"ea",第二步将“eat”变成“ea”
1.2分析
1.确定dp数组以及下标含义
dp[i] [j] :以i-1为结尾的字符串word1和以j-1位结尾的字符串word2,想要达到相同,所需要删除元素的最少次数。
2.确定递推公式
(1)当word1[i-1]与word2[j-1]相同的时候
dp[i] [j] = dp[i - 1] dp[j-1]
(2)当word1[i-1]与word2[j-1]不相同的时候
(2.1)删word1[i-1],最少操作次数为dp[i-1] [j] + 1
(2.2)删word2[j-1],最少操作次数为dp[i] [j-1] +1
(2.3)同时删除word1[i-1]和word2[j-1],操作的最少次数为dp[i-1] [j-1]+2
取最小值,得递推公式:dp[i] [j] = min(min(dp[i-1] [j-1]+2,dp[i-1] [j]+1), dp[i] [j-1] + 1)
3.dp数组如何初始化
dp[i] [0]:word2为空字符串,以i-1为结尾的字符串word1需要删除多少个元素,才能和word2相同?显然dp[i] [0] = i
dp[0] [j]同理:
vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1));
for(int i = 0 ; i<=word1.size(); i++) dp[i] [0] =i;
for(int j = 0 ; j <= word2.size(); j++) dp[0] [j] = j;
4.确定遍历顺序
从上到下,从左到右。
5.举例推导dp数组
1.3 代码
class Solution {
public:
int minDistance(string word1, string word2) {
// 创建动态规划数组,行数为 word1 的长度加一,列数为 word2 的长度加一
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
// 初始化第一行和第一列
for (int i = 0; i <= word1.size(); i++) dp[i][0] = i; // 当 word2 为空时,将 word1 中的所有字符都删除,需要的操作数为 i
for (int j = 0; j <= word2.size(); j++) dp[0][j] = j; // 当 word1 为空时,将 word2 中的所有字符都插入到 word1 中,需要的操作数为 j
// 递推计算 dp 数组中的其他元素
for (int i = 1; i <= word1.size(); i++) {
for (int j = 1; j <= word2.size(); j++) {
if (word1[i - 1] == word2[j - 1]) {
// 如果 word1 的第 i 个字符和 word2 的第 j 个字符相同,那么将不需要进行操作
dp[i][j] = dp[i - 1][j - 1];
} else {
// 当word1[i-1]与word2[j-1]不相同的时候
// 删word1[i - 1],最少操作次数为dp[i - 1][j] + 1
// 删word2[j - 1],最少操作次数为dp[i][j - 1] + 1
// 同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1][j - 1] + 2
// 取这三种操作的最小值
dp[i][j] = min(min(dp[i-1][j-1]+2,dp[i-1][j]+1), dp[i][j-1] + 1);
}
}
}
// 返回 dp 数组的最后一个元素,即将 word1 转换为 word2 需要的最少操作数
return dp[word1.size()][word2.size()];
}
};
2.力扣72. 编辑距离
2.1 题目描述
题目描述:
给你两个单词word1和word2,请你计算出word1转换成word2所需要的最小操作数。
例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’)
2.2 分析
1.确定dp数组以及下标的含义
dp[i] [j]表示以下标i-1为结尾的字符串word1和以下标j-1为结尾的字符串word2,最近的编辑距离为dp[i] [j].
2.确定递推公式
if(word1[i-1] == word23[j-1])
不操作
if(word1[i-1] !=word2[j-1])
增
删
换
如上所视,一共四种情况:
if(word1[i-1] == word23[j-1])说明不需要任何操作,递推公式:dp[i] [j] = dp[i-1] [j-1]
if(word1[i-1] !=word2[j-1]):
(1) word1删除一个元素,那么就是以下标i-2为结尾的word1与j-1为结尾的word2的最近编辑距离再加上一个操作。
dp[i] [j] = dp[i-1] [j] + 1
(2)word2删除一个元素,那么就是以下标i-1为结尾的word1与j-2为结尾的word2的最近编辑距离在加上一个操作。
dp[i] [j] =dp[i] [j-1] + 1
(3)替换元素,word1替换word1[i-1],使其与word2[j-1]相同。
dp[i] [j] =dp[i-1] [j-1] +1
综上取最小得递推公式:dp[i] [j] = min(min(dp[i-1] [j-1],dp[i-1] [j]),dp[i] [j-1]) + 1;
3.dp数组如何初始化
dp[i] [j]:表示以下标i-1为结尾的字符串word1和以下标j-1为结尾的字符串成word2,最近的编辑距离为dp[i] [j].
dp[i] [0]:以下标i-1为结尾的字符串word1和空字符串word2,最近编辑距离为dp[i] [0].
dp[i] [0]表示对word1里的元素全部做删除操作,dp[i] [0] = i;
同理:
dp[0] [j] = j;
for(int i = 0 ; i<= word1.size(); i++) dp[i] [0] = i;
for(int j = 0; j <=word2.size(); j++) dp[0] [j] = j;
4.确定遍历顺序
从上到下,从左到右。
5.举例推导dp数组
文章来源:https://www.toymoban.com/news/detail-422437.html
2.3 代码
class Solution {
public:
int minDistance(string word1, string word2) {
// 创建一个二维数组来存储最小编辑距离
// dp[i][j]表示将word1的前i个字符转换成word2的前j个字符所需的最小编辑距离
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));
// 初始化第一行和第一列,分别表示将一个字符串转换为空字符串所需的最小编辑距离
for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;
// 计算dp数组中的其他值
for (int i = 1; i <= word1.size(); i++) {
for (int j = 1; j <= word2.size(); j++) {
// 如果word1的第i个字符等于word2的第j个字符
// 则不需要进行任何操作,编辑距离等于dp[i-1][j-1]
if (word1[i - 1] == word2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
}
// 如果word1的第i个字符不等于word2的第j个字符
// 则有三种操作:插入、删除、替换
// 插入:dp[i][j-1]表示将word1的前i个字符转换成word2的前j-1个字符的最小编辑距离
// 删除:dp[i-1][j]表示将word1的前i-1个字符转换成word2的前j个字符的最小编辑距离
// 替换:dp[i-1][j-1]表示将word1的前i-1个字符转换成word2的前j-1个字符的最小编辑距离
// 由于需要对word1进行操作,因此操作数需要加1
else {
dp[i][j] = min(min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1]) + 1;
}
}
}
// 返回将word1的所有字符转换成word2的所有字符所需的最小编辑距离
return dp[word1.size()][word2.size()];
}
};
3.参考资料
[代码随想录]文章来源地址https://www.toymoban.com/news/detail-422437.html
到了这里,关于算法学习day56的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!