LeetCode 72 Hard 最小距离 Python

def minDistance(self, word1, word2):
    """
    Solution Method With Mine
    算法:动规
    思路:
        首先看题目意思就能很容易地想到用动规,因为是求最小嘛
            下面代码的动规状态建立的是dp[i][j],代表的是word1的第i个位置以前与word2第j个位置以前要建立
        转换最少需要多少步,显然dp[-1][-1]就是要求的目标,可以画一个表看出来,
            dp[i][j] 的值取决于左侧,上面,左上三个位置,分别对应于:
            以horse 和 ros 为例
                左:dp[i][j-1]      --> horse 到 ro 的距离,那么从左侧过来就代表insert ros的s
                上:dp[i-1][j]      --> horse 到 ros 的距离,从上面过来就代表delete horse的e
                左上:dp[i-1][j-1]  --> hors 到 ro  的距离,从左上过来就代表replace horse的e为s
            这里要注意左上是特殊的如果现在词是horss,那么horss到ros的距离和hors到ros的距离是一样的,
            因为末尾的字母都一样,所以不需要+1
            if word1[i] == word2[j]:
                dp[i][j] = 1+ min(left,top,left_top-1)
            else:
                dp[i][j] = 1+ min(left,top,left_top)
            显然边界条件在dp[0][0],dp[0][j],dp[i][0]
            画个表也可以比较清晰的找到他们的关系和值
            要注意的是在边界位置也要考虑word1[i]和word2[j]的关系!比如horse到r的距离,
            显然在hor的时候,因为hor的末尾是r,所以hor的距离和ho是一样的,第一行h到ros的距离计算的时候同理
    """

    n = len(word1)
    m = len(word2)
    if n * m == 0:
        return n + m
    dp = [[float('inf')] * m for _ in range(n)]
    dp[0][0] = 0 if word1[0] == word2[0] else 1
    for j in range(1, m):
        if word1[0] == word2[j]:
            dp[0][j] = dp[0][j - 1]
        else:
            dp[0][j] = dp[0][j - 1] + 1
    for i in range(1, n):
        if word1[i] == word2[0]:
            dp[i][0] = i
        else:
            dp[i][0] = dp[i - 1][0] + 1
    for i in range(1, n):
        for j in range(1, m):
            if word1[i] != word2[j]:
                dp[i][j] = 1 + min(dp[i][j - 1], dp[i - 1][j - 1], dp[i - 1][j])
            else:
                dp[i][j] = 1 + min(dp[i][j - 1], dp[i - 1][j - 1] - 1, dp[i - 1][j])
    return dp[-1][-1]

def minDistance1(self, word1, word2):
    """
    Solution Method
     算法:动规
     思路:
        整体思路和上面的一样,不同的是这里dp状态的下标含义有所不同
        定义dp[n+1][m+1]
        dp[i][j]代表word1从第1个字母到第i个字母与word2第1个字母到第j个字母之间转化时的最小距离
        所以dp[0][0]这类代表空字符串到word2的转化,比如''到'ros',那么这一行dp[0][j]的值自然就是j了
        即全靠insert
        dp的状态转移方程不变。

        这种定义dp的解法更简洁
    """

    n = len(word1)
    m = len(word2)
    if n * m == 0:
        return n + m
    dp = [[float('inf')] * (m + 1) for _ in range(n + 1)]
    for i in range(n + 1):
        dp[i][0] = i
    for j in range(m + 1):
        dp[0][j] = j
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if word1[i - 1] != word2[j - 1]:
                dp[i][j] = 1 + min(dp[i][j - 1], dp[i - 1][j - 1], dp[i - 1][j])
            else:
                dp[i][j] = 1 + min(dp[i][j - 1], dp[i - 1][j - 1] - 1, dp[i - 1][j])
    return dp[-1][-1]

猜你喜欢

转载自blog.csdn.net/qq_28327765/article/details/85868678
今日推荐