编辑距离问题
Posted acodingdg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编辑距离问题相关的知识,希望对你有一定的参考价值。
问题:
https://leetcode-cn.com/problems/edit-distance/
讨论:
这个题我在华为笔试的时候遇到过,直接看懵了。无意中在知乎上发现有人讨论这个题(https://zhuanlan.zhihu.com/p/111409982),稍微弄懂了些皮毛,
所以记录一下。
简单的说一下例子:
有字符串“horse” 和字符串“ros”,问从“horse”转化到“ros”要多少步(包括增加(“hor”>"hors", 增加了一个s),删除("horse"->"hors",删除了一个e),改变("horse"->"horst", 由‘e‘->‘t‘))
这个一般很难想到要用动态规划来做。那么要务是找到递推公式。
从最基本的情况考虑,也就是""->"",需要的步骤是0,那么从""->"ros"最少的步骤则是3(依次增加[r, o, s])。
从"horse"->""的情况同理,是5(依次删除[h,o,r,s,e])。
设dp[i][j]为"horse"[1..i]转换为"ros"[1..j]
那么考虑一下比较现实的“horse”到"ros":“horse”的第i个字符和“ros”第j个做比较的时候
case 1:
horse[i+1] == ros[j+1]
那么不需要多余操作,也就说说dp[i][j] == dp[i+1][j+1]
case 2:
horse[i+1] != ros[j+1]
那么这里的问题就是,如何操作才能让horse[1..i+1] ->ros[1..j+1]了
如题目给出的条件,能够进行的操作有3种,假设实际情况为"hor"->"ro"时出现case 2
1. 增加
也就是说,需要"hor"增加一个字符才能转变成"ro"
如果要计算这次的edit的次数,我们需要知道"hor"->"r"的次数,也就是dp[i+1][j]的值。
原因是,我们需要在"hor"上多加一个字符来使"horo"->"ro","hor"->"r",转换好了以后,再来一个增加操作
2. 删除
这里要让"hor"->"ro"使用删除操作,删除"horse"[i+1]让"hor"->"ro", 那么需要的是"ho"->"ro", 也就是dp[i][j+1]
3. 改变
"hor" -> "ro"使用改操作的时候,需要知道"ho"->"r"的转换需要的操作。
因为是最少的操作数量,所以需要使用min来找到这三种对应的那种操作的数量最小
# word1(horse) to word2(ros) def edit_distance(word1, word2): m = len(word1) n = len(word2) dp = [[0 for _ in range(n+1)] for _ in range(m+1)] for i in range(m+1): for j in range(n+1): if j == 0: dp[i][j] = i # "horse" to "" if i == 0: dp[i][j] = j # "" to "ros" for i in range(1,m+1): for j in range(1, n+1): if word1[i-1] == word2[j-1]: dp[i][j] = dp[i-1][j-1] else: inc = dp[i-1][j] + 1 update = dp[i-1][j-1] + 1 delete = dp[i][j-1] + 1 dp[i][j] = min([inc, update, delete]) return dp[-1][-1] if __name__ == "__main__": res = edit_distance("horse", "ros") print(res)
以上是关于编辑距离问题的主要内容,如果未能解决你的问题,请参考以下文章