leetcode

72、最小编辑距离

动态规划:

dp[i][j]代表 word1i 位置转换成word2j 位置需要最少步数

所以,

word1[i] == word2[j]dp[i][j] = dp[i-1][j-1]

word1[i] != word2[j]dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1

其中,dp[i-1][j-1] 表示替换操作,dp[i-1][j] 表示删除操作,dp[i][j-1]表示插入操作。

注意,针对第一行,第一列要单独考虑,我们引入 '' 下图所示:

image.png

第一行,是 word1 为空变成 word2 最少步数,就是插入操作

第一列,是 word2 为空,需要的最少步数,就是删除操作

自底向上

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        l1 = len(word1)
        l2 = len(word2)
        path_matrix = [[0 for _ in range(l1+1)] for _ in range(l2+1)]
        # path_matrix[0][:] = [i for i in range(l1+1)]
        # path_matrix[:][0] = [i for i in range(l2+1)]
        for w2 in range(l2+1):
            for w1 in range(l1+1):
                if w2 == 0 or w1 == 0:
                    path_matrix[w2][w1] = max(w2, w1)
                    continue
                if word1[w1-1] == word2[w2-1]:
                    path_matrix[w2][w1] = path_matrix[w2-1][w1-1]
                else:
                    path_matrix[w2][w1] = min(path_matrix[w2-1][w1-1],
                                                  path_matrix[w2-1][w1],
                                                  path_matrix[w2][w1-1]) + 1
        return path_matrix[l2][l1]

自顶向下

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        import functools
        @functools.lru_cache(None)
        def helper(i, j):
            if i == len(word1) or j == len(word2):
                return len(word1) - i + len(word2) - j
            if word1[i] == word2[j]:
                return helper(i + 1, j + 1)
            else:
                inserted = helper(i, j + 1)
                deleted = helper(i + 1, j)
                replaced = helper(i + 1, j + 1)
                return min(inserted, deleted, replaced) + 1
        return helper(0, 0)

自顶向下的思考:
从矩阵的0,0位置到i,j位置要向下走i步,向右走j步。
helper(i,j)代表的含义是,从0,0到i,j一步未动,helper(0,0)是指全部消耗完i,j次移动。
helper函数中的第一个if实际在填充上图矩阵的第一行或第一列。

你可能感兴趣的:(leetcode)