LeetCode 第7天 动态规划 (子序列问题 二)编辑距离 python

  • Post author:
  • Post category:python


以下题目来来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/uncrossed-lines

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


1035 不相交的线


在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。

现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足:

nums1[i] == nums2[j]

且绘制的直线不与任何其他连线(非水平线)相交。

请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。

以这种方法绘制线条,并返回可以绘制的最大连线数。

class Solution:
    def maxUncrossedLines(self, nums1: List[int], nums2: List[int]) -> int:
        #求不连续的公共最长子序列
        #d[i][j] 表示nums1 i位字符串之前和nums2 j位字符串之前的不连续的公共最长子序列
        #递推公式 if nums2[j-1]==nums1[i-1]: dp[i][j]=d[i-1][j-1]+1
        # else: d[i][j]=max(dp[i][j-1],d[i-1][j])
        dp=[[0]*(len(nums1)+1) for _ in range(len(nums2)+1)]
 
        for i in range(1,len(nums2)+1):
            for j in range(1,len(nums1)+1):
                if nums1[j-1]==nums2[i-1]: 
                    dp[i][j]=dp[i-1][j-1]+1
                else:
                    dp[i][j]=max(dp[i][j-1],dp[i-1][j])

        return dp[-1][-1]


115 不同子序列



编辑距离问题


给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。

字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,“ACE” 是 “ABCDE” 的一个子序列,而 “AEC” 不是)

题目数据保证答案符合 32 位带符号整数范围

class Solution:
    def numDistinct(self, s: str, t: str) -> int:
        #dp[i][j]表示 第i位之前的s拥有第j位之前的t的个数
        #递推关系 if s[i-1]!=t[j-1]: dp[i][j]=dp[i-1][j]
        #else: d[i][j]=dp[i-1][j-1]+dp[i-1][j] 用s[i-1]匹配 或者不用s[i-1]匹配
        dp=[[0]*(len(t)+1) for _ in range(len(s)+1)]

        for i in range(len(s)):
            dp[i][0]=1
        
        for i in range(1,len(s)+1):
            for j in range(1,len(t)+1):
                if s[i-1]==t[j-1]:
                    dp[i][j]=dp[i-1][j-1]+dp[i-1][j]
                else:
                    dp[i][j]=dp[i-1][j]
        return dp[-1][-1]


583. 两个字符串的删除操作


给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。

每步 可以删除任意一个字符串中的一个字符。

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        #dp[i][j] 使得第i位之前的word1与第j位之前的word2相同的最小操作数
        #递推关系:if word1[i-1]==word2[j-1]: dp[i][j]=dp[i-1][j-1]
        #else: dp[i][j]=min(dp[i-1][j],dp[i][j-1])
        dp=[[0]*(len(word2)+1) for _ in range(len(word1)+1)]
        for i in range(len(word1)+1):
            dp[i][0]=i
        for i in range(len(word2)+1):
            dp[0][i]=i
        
        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]+2,dp[i-1][j]+1,dp[i][j-1]+1)
        return dp[-1][-1]


72 编辑距离


给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

插入一个字符

删除一个字符

替换一个字符

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        #dp[i][j]表示 i位之前的word1 变为j位之前的word2最少步数
        #递推公式 if word1[i-1]==word2[j-1]:  dp[i][j]=dp[i-1][j-1]
        # 删除和添加是一种情况word1删除或者word2删除 另一种是替换 else :dp[i][j]=min(dp[i-1][j-1]+1,dp[i-1][j]+1,dp[i][j-1]+1)
        dp=[[0]*(len(word2)+1) for _ in range(len(word1)+1)]
        for i in range(len(word1)+1):
            dp[i][0]=i
        for i in range(len(word2)+1):
            dp[0][i]=i
        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]+1,dp[i-1][j]+1,dp[i][j-1]+1)
        return dp[-1][-1]



版权声明:本文为m0_43424109原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。