基于动态规划的编辑距离(Levenshtein Distance)算法详解
题目描述
编辑距离(Levenshtein Distance)是衡量两个字符串相似度的经典算法,通过计算将一个字符串转换为另一个字符串所需的最少编辑操作次数(包括插入、删除、替换字符)。该算法在拼写检查、DNA序列比对、机器翻译评估等领域有广泛应用。
解题过程
1. 问题定义
设字符串 \(A = a_1a_2...a_m\) 和 \(B = b_1b_2...b_n\),编辑距离 \(d(m, n)\) 表示将 \(A\) 转换为 \(B\) 的最小操作次数。编辑操作包括:
- 插入:在 \(A\) 中插入一个字符(成本为1)
- 删除:从 \(A\) 中删除一个字符(成本为1)
- 替换:将 \(A\) 中的一个字符替换为 \(B\) 中的字符(成本为1,若字符相同则成本为0)
2. 动态规划状态定义
构建二维数组 \(dp[i][j]\),表示子串 \(A[0:i]\) 到 \(B[0:j]\) 的编辑距离。其中 \(0 \leq i \leq m\),\(0 \leq j \leq n\)。
3. 状态转移方程
- 初始状态:
- 当 \(i=0\) 时,\(dp[0][j] = j\)(将空串转换为 \(B[0:j]\) 需 \(j\) 次插入)
- 当 \(j=0\) 时,\(dp[i][0] = i\)(将 \(A[0:i]\) 转换为空串需 \(i\) 次删除)
- 递推关系(对于 \(i>0, j>0\)):
\[ dp[i][j] = \min \begin{cases} dp[i-1][j] + 1 & \text{删除 } a_i \\ dp[i][j-1] + 1 & \text{插入 } b_j \\ dp[i-1][j-1] + \text{cost} & \text{替换操作} \end{cases} \]
其中 \(\text{cost} = 0\) 若 \(a_i = b_j\),否则 \(\text{cost} = 1\)。
4. 计算步骤示例
以 \(A = "kitten"\) 和 \(B = "sitting"\) 为例:
- 初始化 \(dp\) 表(第一行和第一列为索引值):
s i t t i n g 0 1 2 3 4 5 6 7 k 1 i 2 t 3 t 4 e 5 n 6 - 逐行计算:
- \(dp[1][1]\):比较 \(a_1='k'\) 和 \(b_1='s'\),取 \(\min(1+1, 1+1, 0+1) = 1\)(替换)
- 最终 \(dp[6][7] = 3\)(删除 'k'、替换 'e'→'i'、插入 'g')
5. 算法优化
实际应用中可优化空间复杂度至 \(O(\min(m, n))\),仅保留当前行和上一行的数据。
6. 应用扩展
- 加权编辑距离:为不同操作分配不同权重(如语音识别中替换成本可能更低)
- 回溯操作路径:通过记录决策路径还原具体编辑步骤。
通过以上步骤,编辑距离算法将字符串转换问题转化为可计算的动态规划模型,兼顾效率与实用性。