计算两个字符串的编辑距离,也称为 Levenshtein 距离。该算法用于计算将字符串 a
转换为字符串 b
所需的最少操作次数(插入、删除或替换)。
修复和优化
当前代码存在一些错误和优化空间:
- 索引范围错误:外层循环应包括字符串的最后一个字符,即应从 0 开始遍历到字符串的长度。
- 初始化错误:动态规划数组需要适当初始化边界条件。
- 内层逻辑错误:需修正字符匹配的逻辑和 DP 转移的逻辑。
- 变量命名和代码结构的优化:提高可读性。
修复和优化后的代码
pythonCopy codedef distance_between(a, b):
# 确定 DP 表的大小
n, m = len(a), len(b)
dp = [[0] * (m + 1) for _ in range(n + 1)]
# 初始化 DP 表的边界条件
for i in range(n + 1):
dp[i][0] = i # 将 a 的前 i 个字符转为空的操作数
for j in range(m + 1):
dp[0][j] = j # 将 b 的前 j 个字符插入的操作数
# 填充 DP 表
for i in range(1, n + 1):
for j in range(1, m + 1):
if a[i - 1] == b[j - 1]:
dp[i][j] = dp[i - 1][j - 1] # 字符相同,不需要操作
else:
dp[i][j] = min(
dp[i - 1][j] + 1, # 删除 a[i-1]
dp[i][j - 1] + 1, # 插入 b[j-1]
dp[i - 1][j - 1] + 1 # 替换 a[i-1] 为 b[j-1]
)
return dp[n][m]
# 示例测试
a = "kitten"
b = "sitting"
print(distance_between(a, b)) # 输出:3
优化后的代码解释
- DP 表的初始化:
dp[i][0]
表示将字符串a
的前i
个字符转换为空串所需的最小操作数,即i
次删除。dp[0][j]
表示将空串转换为字符串b
的前j
个字符所需的最小操作数,即j
次插入。
- DP 转移方程:
- 如果
a[i-1] == b[j-1]
,则不需要操作,dp[i][j] = dp[i-1][j-1]
。 - 如果
a[i-1] != b[j-1]
,则需要在以下三种操作中取最小值:- 删除操作:
dp[i-1][j] + 1
,表示删除a[i-1]
。 - 插入操作:
dp[i][j-1] + 1
,表示在a
中插入b[j-1]
。 - 替换操作:
dp[i-1][j-1] + 1
,表示将a[i-1]
替换为b[j-1]
。
- 删除操作:
- 如果
- 时间复杂度:
O(n * m)
,其中n
和m
分别是字符串a
和b
的长度。 - 空间复杂度:
O(n * m)
,用于存储 DP 表。
进一步优化
如果空间是一个瓶颈,可以使用滚动数组将空间复杂度优化为 O(min(n, m))
,不过这会增加代码的复杂性。