返回
动态规划经典题:编辑距离详解,掌握算法精髓
人工智能
2023-09-22 05:05:59
动态规划经典教学题:编辑距离详解
前言
大家好,我是算法工程师小明。今天,我们一起来学习动态规划的经典教学题——编辑距离。这道题是算法面试中常考题,掌握它的解题思路和算法实现,对提升算法面试通过率大有裨益。
什么是编辑距离?
编辑距离,又称Levenshtein距离,衡量两个字符串之间的相似度。它表示将一个字符串转换为另一个字符串所需的最小编辑操作数,这些操作包括:
- 插入一个字符
- 删除一个字符
- 替换一个字符
问题
给定两个字符串 str1
和 str2
,计算将 str1
转换为 str2
所需的最小编辑距离。
动态规划解法
我们使用动态规划来解决这个问题。首先,我们创建一张二维表 dp
,其中 dp[i][j]
表示将 str1[0:i]
转换为 str2[0:j]
所需的最小编辑距离。
状态转移方程
dp
表的计算方式如下:
dp[i][j] = min(dp[i-1][j] + 1, dp[i][j-1] + 1, dp[i-1][j-1] + (str1[i] != str2[j]))
其中:
dp[i-1][j] + 1
:从str1[0:i-1]
转换为str2[0:j]
,然后在str1
末尾插入一个字符。dp[i][j-1] + 1
:从str1[0:i]
转换为str2[0:j-1]
,然后在str2
末尾删除一个字符。dp[i-1][j-1] + (str1[i] != str2[j])
:从str1[0:i-1]
转换为str2[0:j-1]
,然后替换第i
个字符(如果str1[i]
与str2[j]
不相等)。
初始化
dp[0][j] = j
dp[i][0] = i
这是因为将空字符串转换为一个非空字符串需要 j
次插入,而将一个非空字符串转换为空字符串需要 i
次删除。
计算
从 dp[1][1]
开始,按照状态转移方程计算 dp
表中的所有元素。
结果
dp[m][n]
,其中 m
和 n
分别是 str1
和 str2
的长度,即为将 str1
转换为 str2
所需的最小编辑距离。
代码实现
def edit_distance(str1, str2):
m, n = len(str1), len(str2)
dp = [[0] * (n + 1) for _ in range(m + 1)]
# 初始化
for i in range(m + 1):
dp[i][0] = i
for j in range(n + 1):
dp[0][j] = j
# 计算
for i in range(1, m + 1):
for j in range(1, n + 1):
dp[i][j] = min(
dp[i-1][j] + 1,
dp[i][j-1] + 1,
dp[i-1][j-1] + (str1[i-1] != str2[j-1])
)
return dp[m][n]
示例
str1 = "abc"
str2 = "abd"
result = edit_distance(str1, str2)
print(result) # 输出:1
总结
编辑距离是动态规划中的经典问题,它衡量两个字符串之间的相似度,并提供将一个字符串转换为另一个字符串的最小编辑操作数。通过掌握这道题的解题思路和代码实现,我们可以更好地理解动态规划算法,并提升算法面试通过率。