编辑距离(Edit Distance)问题
字数 1335 2025-11-07 12:34:03

编辑距离(Edit Distance)问题

题目描述
编辑距离(也称为Levenshtein距离)是指将一个字符串转换成另一个字符串所需的最少单字符编辑操作次数。允许的编辑操作包括:插入一个字符、删除一个字符、替换一个字符。例如,将"horse"转换为"ros"的编辑距离是3(删除'h'->"orse",删除'o'->"rse",删除'e'->"rs",但实际最优解是:horse->rorse(替换'h'为'r')->rose(替换's'为'o')->ros(删除'e'))。

解题思路
这个问题通常使用动态规划来解决。我们定义一个二维数组dp[i][j],表示将字符串word1的前i个字符转换为字符串word2的前j个字符所需的最小编辑操作次数。

详细步骤

  1. 状态定义
    dp[i][j]表示将word1[0..i-1](前i个字符)转换为word2[0..j-1](前j个字符)的最小编辑距离。

  2. 初始化边界情况

    • 如果word1的前i个字符要变成空字符串word2的前0个字符,需要删除i次(即dp[i][0] = i)。
    • 如果空字符串word1要变成word2的前j个字符,需要插入j次(即dp[0][j] = j)。
  3. 状态转移方程
    对于每个ij(从1开始),考虑word1[i-1]word2[j-1]

    • 如果word1[i-1] == word2[j-1],则不需要操作,dp[i][j] = dp[i-1][j-1]
    • 如果字符不相等,则考虑三种操作,取最小值加1:
      • 插入:在word1的前i个字符后插入word2[j-1],使它们匹配,相当于word2的j-1已经匹配,所以dp[i][j] = dp[i][j-1] + 1
      • 删除:删除word1[i-1],相当于word1的前i-1个字符和word2的前j个字符匹配,所以dp[i][j] = dp[i-1][j] + 1
      • 替换:将word1[i-1]替换为word2[j-1],相当于word1的前i-1和word2的前j-1匹配,然后替换一次,所以dp[i][j] = dp[i-1][j-1] + 1
        因此,状态转移方程为:
    if word1[i-1] == word2[j-1]:
        dp[i][j] = dp[i-1][j-1]
    else:
        dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
    
  4. 填表顺序
    由于dp[i][j]依赖于左方、上方和左上方,因此按行从左到右、从上到下填充dp表。

  5. 结果提取
    最终结果在dp[len(word1)][len(word2)]中。

举例说明
word1 = "horse", word2 = "ros"为例:

  • 初始化dp表(6行4列,因为字符串长度分别为5和3):
    dp[0][0] = 0, dp[1][0] = 1, ..., dp[5][0] = 5  
    dp[0][1] = 1, dp[0][2] = 2, dp[0][3] = 3
    
  • 计算dp[1][1]:比较'h'和'r',不相等,取min(dp[0][1], dp[1][0], dp[0][0])+1 = min(1,1,0)+1=1。
  • 最终dp[5][3]=3,即编辑距离为3。

复杂度分析

  • 时间复杂度:O(m*n),其中m和n分别是两个字符串的长度。
  • 空间复杂度:O(m*n),可以优化到O(min(m,n))。
编辑距离(Edit Distance)问题 题目描述 编辑距离(也称为Levenshtein距离)是指将一个字符串转换成另一个字符串所需的最少单字符编辑操作次数。允许的编辑操作包括:插入一个字符、删除一个字符、替换一个字符。例如,将"horse"转换为"ros"的编辑距离是3(删除'h'->"orse",删除'o'->"rse",删除'e'->"rs",但实际最优解是:horse->rorse(替换'h'为'r')->rose(替换's'为'o')->ros(删除'e'))。 解题思路 这个问题通常使用动态规划来解决。我们定义一个二维数组 dp[i][j] ,表示将字符串 word1 的前 i 个字符转换为字符串 word2 的前 j 个字符所需的最小编辑操作次数。 详细步骤 状态定义 设 dp[i][j] 表示将 word1[0..i-1] (前i个字符)转换为 word2[0..j-1] (前j个字符)的最小编辑距离。 初始化边界情况 如果 word1 的前 i 个字符要变成空字符串 word2 的前0个字符,需要删除 i 次(即 dp[i][0] = i )。 如果空字符串 word1 要变成 word2 的前 j 个字符,需要插入 j 次(即 dp[0][j] = j )。 状态转移方程 对于每个 i 和 j (从1开始),考虑 word1[i-1] 和 word2[j-1] : 如果 word1[i-1] == word2[j-1] ,则不需要操作, dp[i][j] = dp[i-1][j-1] 。 如果字符不相等,则考虑三种操作,取最小值加1: 插入 :在 word1 的前i个字符后插入 word2[j-1] ,使它们匹配,相当于 word2 的j-1已经匹配,所以 dp[i][j] = dp[i][j-1] + 1 。 删除 :删除 word1[i-1] ,相当于 word1 的前i-1个字符和 word2 的前j个字符匹配,所以 dp[i][j] = dp[i-1][j] + 1 。 替换 :将 word1[i-1] 替换为 word2[j-1] ,相当于 word1 的前i-1和 word2 的前j-1匹配,然后替换一次,所以 dp[i][j] = dp[i-1][j-1] + 1 。 因此,状态转移方程为: 填表顺序 由于 dp[i][j] 依赖于左方、上方和左上方,因此按行从左到右、从上到下填充dp表。 结果提取 最终结果在 dp[len(word1)][len(word2)] 中。 举例说明 以 word1 = "horse" , word2 = "ros" 为例: 初始化dp表(6行4列,因为字符串长度分别为5和3): 计算 dp[1][1] :比较'h'和'r',不相等,取min(dp[ 0][ 1], dp[ 1][ 0], dp[ 0][ 0 ])+1 = min(1,1,0)+1=1。 最终 dp[5][3] =3,即编辑距离为3。 复杂度分析 时间复杂度:O(m* n),其中m和n分别是两个字符串的长度。 空间复杂度:O(m* n),可以优化到O(min(m,n))。