BM75 编辑距离(一)
知识点动态规划字符串
描述
给定两个字符串 str1 和 str2 ,请你算出将 str1 转为 str2 的最少操作数。你可以对字符串进行3种操作:1.插入一个字符2.删除一个字符3.修改一个字符。
字符串长度满足 ,保证字符串中只出现小写英文字母。
示例1
输入:
"nowcoder","new"
复制返回值:
6
复制说明:
"nowcoder"=>"newcoder"(将'o'替换为'e'),修改操作1次
"nowcoder"=>"new"(删除"coder"),删除操作5次
示例2
输入:
"intention","execution"
复制返回值:
5
复制说明:
一种方案为:
因为2个长度都是9,后面的4个后缀的长度都为"tion",于是从"inten"到"execu"逐个修改即可
示例3
输入:
"now","nowcoder"
复制返回值:
5
题解
思路:
- 使用dp[i][k]表示str1中前i个字符串变成str2中前k个字符串所需要的最小步骤
- 初始条件:dp[0][k] = k表示从0个字符变成k的所需要的步骤,dp[i][0]= i表示从i个字符变成0的所需要的步骤
- 状态转移方程:
- 如果str1[i] == str2[k],则dp[i][k] = dp[i-1][k-1]
- 否则str1[0,i]转变成str2[0,k],可以有以下三种方法,选取最小的一种即可:
- 删除str1[i],则dp[i][k] = dp[i-1][k] + 1
- 删除str2[k],则dp[i][k] = dp[i][k-] + 1
- 修改str1[i]为str2[k],则dp[i][k] = dp[i-1][k-1] + 1
代码如下:
using namespace std;
int editDistance(string str1, string str2)
{
if (str1.size() == 0 || str2.size() == 0)
{
return str1.size() + str2.size();
}
std::vector<std::vector<int>> dp(str1.size() + 1, std::vector<int>(str2.size() + 1, 0));
for (int i = 0; i <= str1.size(); ++i)
{
for (int k = 0; k <= str2.size(); ++k)
{
if (i == 0)
{
dp[i][k] = k;
continue;
}
if (k == 0)
{
dp[i][k] = i;
continue;
}
if (str1[i - 1] == str2[k - 1])
{
dp[i][k] = dp[i - 1][k - 1];
}
else
{
dp[i][k] = std::min(std::min(dp[i - 1][k - 1], dp[i - 1][k]), dp[i][k - 1]) + 1;
}
}
}
return dp[str1.size()][str2.size()];
}