题目LeetCode 72
给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例
示例 1:
输入: word1 = "horse", word2 = "ros"
输出: 3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
Python解法
代码示例
python
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
n, m =len(word1), len(word2)
dp = [[0] * (m + 1) for _ in range(n + 1)]
for i in range(n + 1):
dp[i][0] = i
for j in range(m + 1):
dp[0][j] = j
for i in range(1,n + 1):
for j in range(1,m + 1):
delete_dp = dp[i - 1][j] + 1
insert_dp = dp[i][j - 1] + 1
replace_dp = dp[i - 1][j - 1]
if word1[i - 1] != word2[j - 1]:
replace_dp += 1
dp[i][j] = min(delete_dp, insert_dp, replace_dp)
return dp[n][m]
解释
1,边界初始化
python
for i in range(n + 1):
dp[i][0] = i
word2 为空串,只能把 word1 逐个删除:有几个字符就删几次。
python
for j in range(m + 1):
dp[0][j] = j
word1 为空串,只能逐个插入 word2 字符:有几个字符就插几次。
2,状态转换
(1)删除操作
python
delete_op = dp[i - 1][j] + 1
word1 删掉第 i 个字符,问题缩小为:word1前i-1个 匹配 word2前j个,操作 + 1。
(2)插入操作
python
insert_op = dp[i][j - 1] + 1
word1 插入一个字符匹配 word2[j-1],问题缩小为:word1前i个 匹配 word2前j-1个,操作 + 1。
(3)替换操作
python
replace_op = dp[i - 1][j - 1]
if word1[i - 1] != word2[j - 1]:
replace_op += 1
如果 word1[i-1] == word2[j-1]:字符相等,不用操作 ,直接继承 dp[i-1][j-1]
如果不相等:替换一次,操作数 + 1
(4)取最小值
python
dp[i][j] = min(delete_op, insert_op, replace_op)
三种操作选步数最少的。
过程简单演示
以 word1 = "ho",word2 = "ro" 为例

Java解法
代码示例
java
class Solution {
public int minDistance(String word1, String word2) {
int n = word1.length();
int m = word2.length();
// dp[i][j]:word1前i个字符 → word2前j个字符 的最小编辑距离
int[][] dp = new int[n + 1][m + 1];
// 边界初始化:word2 为空,只能删除 word1
for (int i = 0; i <= n; i++) {
dp[i][0] = i;
}
// 边界初始化:word1 为空,只能插入 word2
for (int j = 0; j <= m; j++) {
dp[0][j] = j;
}
// 动态规划填表
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// 删除操作:删掉 word1 第 i 个字符
int delete = dp[i - 1][j] + 1;
// 插入操作:给 word1 插入一个字符匹配 word2 第 j 个
int insert = dp[i][j - 1] + 1;
// 替换 / 不操作:看末尾字符是否相等
int replace = dp[i - 1][j - 1];
if (word1.charAt(i - 1) != word2.charAt(j - 1)) {
replace++;
}
// 三种操作取最小
dp[i][j] = Math.min(Math.min(delete, insert), replace);
}
}
return dp[n][m];
}
}
C++解法
代码示例
cpp
class Solution {
public:
int minDistance(string word1, string word2) {
int n = word1.size();
int m = word2.size();
// dp[i][j]:word1前i个字符 转为 word2前j个字符 的最小编辑距离
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
// 边界1:word2为空,只能不断删除word1
for (int i = 0; i <= n; ++i) {
dp[i][0] = i;
}
// 边界2:word1为空,只能不断插入word2
for (int j = 0; j <= m; ++j) {
dp[0][j] = j;
}
// 遍历填充DP表
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
// 1. 删除操作
int del = dp[i - 1][j] + 1;
// 2. 插入操作
int ins = dp[i][j - 1] + 1;
// 3. 替换 / 无需操作
int rep = dp[i - 1][j - 1];
// 当前字符不同,需要替换,操作数+1
if (word1[i - 1] != word2[j - 1]) {
rep += 1;
}
// 取三种操作最小值
dp[i][j] = min({del, ins, rep});
}
}
return dp[n][m];
}
};