区间动态规划例题:编辑距离问题(带权重版本)
题目描述
给定两个字符串 word1 和 word2,以及三种操作的权重:
- 插入一个字符的成本为
insertCost - 删除一个字符的成本为
deleteCost - 替换一个字符的成本为
replaceCost(若两字符相同,替换成本为0)
求将 word1 转换为 word2 所需的最小总成本。
示例
输入:
word1 = "horse", word2 = "ros"
insertCost = 1, deleteCost = 1, replaceCost = 1
输出:
3
解释:
将 "horse" 转为 "ros" 的一种最优操作序列(总成本=3):
- 删除 'h' → "orse"(成本=1)
- 删除 'o' → "rse"(成本=1)
- 替换 's' 为 'o' → "roe"(成本=1?需检查:实际应为替换 's' 为 'o' 后得 "roe",但目标为 "ros",此处需修正。正确步骤见后文详细推导)
解题步骤
1. 定义状态
设 dp[i][j] 表示将 word1 的前 i 个字符(即 word1[0:i-1])转换为 word2 的前 j 个字符(即 word2[0:j-1])所需的最小成本。
- 初始状态:
dp[0][0] = 0(两个空字符串相互转换成本为0)
2. 初始化边界情况
- 将
word1的前i个字符转为空字符串word2[0:0](即j=0):需删除word1的所有i个字符,成本为i * deleteCost。dp[i][0] = i * deleteCost (i从0到len(word1)) - 将空字符串
word1[0:0]转为word2的前j个字符:需插入word2的所有j个字符,成本为j * insertCost。dp[0][j] = j * insertCost (j从0到len(word2))
3. 状态转移方程
对于每个 i ≥ 1 和 j ≥ 1,考虑对 word1[i-1] 和 word2[j-1] 的操作:
-
情况1:直接匹配或替换
若word1[i-1] == word2[j-1],则无需替换,成本为dp[i-1][j-1]。
若字符不同,则替换word1[i-1]为word2[j-1],成本为dp[i-1][j-1] + replaceCost。
综上:cost_match_replace = dp[i-1][j-1] + (0 if word1[i-1]==word2[j-1] else replaceCost) -
情况2:删除
word1[i-1]
删除当前字符后,需将word1的前i-1字符转为word2的前j字符,成本为dp[i-1][j] + deleteCost。 -
情况3:插入
word2[j-1]
在word1的前i字符后插入word2[j-1],此时word1的前i字符需匹配word2的前j-1字符,成本为dp[i][j-1] + insertCost。
状态转移方程:
dp[i][j] = min(
cost_match_replace,
dp[i-1][j] + deleteCost,
dp[i][j-1] + insertCost
)
4. 示例推导(word1="horse", word2="ros")
权重:insertCost=1, deleteCost=1, replaceCost=1
初始化 dp 表(行列数=len(word1)+1, len(word2)+1):
| "" | "r" | "ro" | "ros" | |
|---|---|---|---|---|
| "" | 0 | 1 | 2 | 3 |
| "h" | 1 | |||
| "ho" | 2 | |||
| "hor" | 3 | |||
| "hors" | 4 | |||
| "horse | 5 |
逐步填充:
dp[1][1]("h"→"r"):
替换成本=0+1=1('h'≠'r'),删除成本=1+1=2,插入成本=0+1=1 → min=1dp[1][2]("h"→"ro"):
替换('h'→'o')=1+1=2,删除=dp[0][2]+1=2+1=3,插入=dp[1][1]+1=1+1=2 → min=2- 继续计算至
dp[5][3]("horse"→"ros"),最终结果为3。
5. 复杂度分析
- 时间复杂度:O(mn),其中 m、n 为两字符串长度。
- 空间复杂度:可优化至 O(min(m,n)),但基础版本为 O(mn)。
关键点
- 权重不同时,需根据实际成本选择操作。
- 若替换成本较高,可能优先选择删除+插入组合。
- 边界初始化需严格对应操作含义。