「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」。
583. 两个字符串的删除操作
题目描述
给定两个单词 word1
和 word2
,返回使得 word1
和 word2
**相同所需的最小步数。
每步 可以删除任意一个字符串中的一个字符。
示例 1:
输入: word1 = "sea", word2 = "eat"
输出: 2
解释: 第一步将 "sea" 变为 "ea" ,第二步将 "eat "变为 "ea"
复制代码
示例 2:
输入: word1 = "leetcode", word2 = "etco"
输出: 4
复制代码
解析
/**
* @brief 动态规划
* 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][j - 1];
*
* (2)当word1[i-1]与word2[j-1]不等时,再分情况:
* a. 删除word1[i-1]: dp[i][j] = dp[i-1][j]+1
* b. 删除word2[j-1]: dp[i][j] = dp[i][j-1]+1
* c. 删除word1[i-1] 和 word2[j-1]: dp[i][j] = dp[i-1][j-1]+2
* 取最小值:dp[i][j] = min({dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+2});
* 3、初始化dp数组
* dp[i][0]: 表示当word2为空时,以i-1结尾的字符串word1需要删除元素的最小次数。
* dp[i][0] = i;
* dp[0][j]: 表示当word1为空时,以j-1结尾的字符串word2需要删除元素的最小次数。
* dp[0][j] = j;
*
* 4、确定遍历顺序
* 由dp[i][j] = dp[i - 1][j - 1]以及 dp[i][j] = min(min(dp[i - 1][j]+1, dp[i][j - 1]+1) ,dp[i - 1][j - 1] + 2)可以看出dp[i][j]都是根据左上方、正上方、正左方推出来的。
* 所以遍历的时候一定是从上到下,从左到右,这样保证dp[i][j]可以根据之前计算出来的数值进行计算。
*
*/
复制代码
代码
class Solution
{
public:
int minDistance(string word1, string word2)
{
// 定义dp数组
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
// 初始化 dp[i][0]
for (int i = 0; i <= word1.size(); i++)
{
dp[i][0] = i;
}
// 初始化 dp[0][j]
for (int j = 0; j <= word2.size(); j++)
{
dp[0][j] = j;
}
// 遍历顺序
for (int i = 1; i <= word1.size(); i++)
{
for (int j = 1; j <= word2.size(); j++)
{
// 递推公式
if (word1[i - 1] == word2[j - 1])
{
dp[i][j] = dp[i - 1][j - 1];
}
else
{
dp[i][j] = min({dp[i - 1][j] + 1,
dp[i][j - 1] + 1,
dp[i - 1][j - 1] + 2});
}
}
}
return dp[word1.size()][word2.size()];
}
};
复制代码