【动态规划】关于编辑距离计算的思考
天下难事,必作于易。 -------- 老子·德经·第六十三章
题目见leetcode:72. 编辑距离
在发布这篇文章之前,关于动态规划算法的运用,我依然是云里雾里,不知题目之所云。幸运的是,在学习了多位up主的教学视频后,对该算法有了一些见地,希望尽自己最大努力将编辑距离的求解过程完整叙述。 【----笔者云】
我将遵循以下原则进行内容分享:
1.如果一件事无法被理解,只是因为它的细节未被完全掌握,而不是我不够聪明;
2.如果事情过于复杂,无从下手,那就拆解它;
3.如果事情依然无法被完美解决,那就考虑这件事本身是否真正值得被解决
1.拆解题目
- 编辑距离:word1变换为word2的操作次数
- 操作:插入,删除,替换(每执行一次,操作数+1)
- 判断条件:衡量标准是word1[i-1] == word2[j-1]
注意:word1插入一个字符后,与word2相同,等价于word2删除一个字符后与word1相同
2.编程思路
- 设置dp[i][j]最少操作数
- dp[i][]记录word1的操作
- dp[][j]记录word2的操作
- 记录状态
- word1删除一个字符满足条件:dp[i][j] = dp[i-1][j] + 1
- word1插入一个字符满足条件:dp[i][j] = dp[i][j-1] + 1
- word1替换一个字符满足条件:dp[i][j] = dp[i-1][j-1] + 1
- word1无操作即满足条件:dp[i][j] = dp[i-1][j-1]
注意:为什么设置dp[i][j],而条件设置为word1[i-1] == word2[j-1]?
方便dp数组初始化,其中dp[-1][j]与dp[i][-1]就代表,将word1和word2转换为空字符串的最小操作数。
3.求解代码
class Solution(object):
def minDistance(self, word1, word2):
"""
:type word1: str
:type word2: str
:rtype: int
"""
n = len(word1)
m = len(word2)
if n * m == 0:
return n + m
dp = [[0] * (m + 1) for _ in range(n + 1)]
for i in range(0,len(word1) + 1):
dp[i][0] = i
for j in range(0,len(word2) + 1):
dp[0][j] = j
for i in range(1, len(word1) + 1):
for j in range(1, len(word2) + 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] + 1, dp[i][j-1] + 1, dp[i-1][j-1] + 1)
return dp[i][j]