编辑距离(Levenshtein 距离)问的是:把字符串 s 改成 t,最少需要几次操作?每一次操作可以是:
- 插入一个字符
- 删除一个字符
- 替换一个字符
经典例子 kitten → sitting 的距离是 3(替换 k→s、替换 e→i、末尾插入 g)。
状态与转移
定义二维 DP:
dp[i][j]= 把s的前i个字符变成t的前j个字符所需的最少操作数
边界:
dp[0][j] = j(空串到 j 个字符要插入 j 次)dp[i][0] = i(i 个字符到空串要删除 i 次)
转移:
- 如果
s[i-1] == t[j-1],免费继承:dp[i][j] = dp[i-1][j-1] - 否则取三个邻居最小值 +1:
- 删除:
dp[i-1][j] + 1 - 插入:
dp[i][j-1] + 1 - 替换:
dp[i-1][j-1] + 1
- 删除:
复杂度
- 时间:O(m·n)
- 空间:O(m·n)(实际可以滚动数组压到 O(min(m, n)))
在动画里看什么
- 表格顶部是目标串
t(含一个ε空前缀),左侧是源串s - 深蓝:当前正在计算的格子;白色:已算出的值;灰色:还没算
- 算完后,暖红单元格描出从
dp[m][n]回溯到dp[0][0]的路径,对应一种具体的编辑方案