编辑距离

来源:互联网 发布:socket.io.js 教程 编辑:程序博客网 时间:2024/06/05 14:17

题目描述:给出两个单词word1和word2,计算出将word1 转换为word2的最少操作次数。你总共三种操作方法:

插入一个字符

删除一个字符

替换一个字符


样例:给出 work1="mart" 和 work2="karma",返回 3


与上一道题“不同的子序列”(详见:点击打开链接)有点类似,都是用动态规划处理两个字符串的的问题。其实我觉得大家做这种东西一定要对方法总结,因为这些东西他都不是很复杂的算法,之所以一开始不会,就是因为没见过,没思路,但是做过类似的东西,再碰到时,就要尝试用之前总结到的东西。

好了,不说废话了。看题,还是通过动态规划建立二维表格,我们记为record吧,record[i][j]表示word1的前 i 项变换成word2的前 j 项所需要的步骤,因为只有3种操作方式,所以我们一一分析一下:

1. 添加:试想,如果word1的前 i 项现在已经变换到word2的前 j - 1 项了,那显然只需要再一步,就是添加字符word2[j]就能变成word2的前 j 项,用状态转移方程来说,record[i][j] = record[i][j - 1] + 1

2. 删除:试想,如果word1的前 i - 1 项现在已经变换到word2的前 j 项了,那么想要word1的前 i 项变换到word2的前 j 项只需要在word1的前 i 项一开始的时候删除word1[i]即可,也就是说,假设word1的前 i - 1 项能通过x步变换到word2的前 j 项,那么word1的前 i 项一定可以通过x + 1步变换到word2的前 j 项,用状态转移方程来说,record[i][j] = record[i - 1][j] + 1

3. 替换:这个就分情况了,假设word1[i] == word2[j],那也就是说,我们只需要考虑word1的前 i - 1 项变换到word2的前 j 项所需的步数就行;而如果word1[i] != word2[j],那么在word1的前 i - 1 项变换到word2的前 j 项所需的步数的基础上,再加一步替换操作,将word1[i] 替换成word2[j]就行,用状态转移方程来说,record[i][j] = record[i - 1][j - 1] + cost,参数cost在word1[i] == word2[j]时为0,在word1[i] != word2[j]时为1


那么,到底应该选择哪种变换模式呢,我们就去计算这三种方式的最小变换步数作为表格当前位置的值就行。


好了,可以给出代码了:

class Solution:     # @param word1 & word2: Two string.    # @return: The minimum number of steps.    def minDistance(self, word1, word2):        m = len(word1)        n = len(word2)        record = [[0 for j in range(n + 1)] for i in range(m + 1)]        # 和上一题“不同的子序列”一样,还是把二维表格拓展一下        # 表格的第一行,第一列分别是两个字符串为空的情况,        # 那么编辑距离当然随着需要变换成的另一字符串的大小变化        for j in range(n + 1):            record[0][j] = j        for i in range(m + 1):            record[i][0] = i                    i = 1        while i < m + 1:            j = 1            while j < n + 1:                cost = 0 if word1[i - 1] == word2[j - 1] else 1                insertion = record[i][j - 1] + 1                deletion = record[i - 1][j] + 1                replacement = record[i - 1][j - 1] + cost                record[i][j] = min(insertion, deletion, replacement)                j += 1            i += 1        return record[m][n]        # write your code here




0 0