欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > 代码随想录算法训练营第50天(py)| 动态规划 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列

代码随想录算法训练营第50天(py)| 动态规划 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列

2025/2/5 20:45:14 来源:https://blog.csdn.net/uncle_tou/article/details/139993291  浏览:    关键词:代码随想录算法训练营第50天(py)| 动态规划 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列

1143.最长公共子序列

力扣链接
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列(未必连续) 的长度。如果不存在 公共子序列 ,返回 0 。

思路

  1. 确定dp含义
    dp[i][j]:长度为[0,i-1]和[0,j-1]的最长公共子序列长度
  2. 确定递推公式
    如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;
    如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。
    即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
if (text1[i - 1] == text2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;
} else {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
  1. 初始化
    全部初始化为0
  2. 确定遍历方向
    从前向后,从上向下
class Solution:def longestCommonSubsequence(self, text1: str, text2: str) -> int:dp = [ [0]*(len(text2)+1) for _ in range(len(text1)+1) ]for i in range(1, len(text1)+1):for j in range(1, len(text2)+1):if text1[i-1]==text2[j-1]:dp[i][j] = dp[i-1][j-1] + 1else:dp[i][j] = max(dp[i][j-1], dp[i-1][j])return dp[-1][-1]

1035.不相交的线

力扣链接
我们在两条独立的水平线上按给定的顺序写下 A 和 B 中的整数。
现在,我们可以绘制一些连接两个数字 A[i] 和 B[j] 的直线,只要 A[i] == B[j],且我们绘制的直线不与任何其他连线(非水平线)相交。
以这种方法绘制线条,并返回我们可以绘制的最大连线数。
在这里插入图片描述

思路

这就是说明在字符串A中 找到一个与字符串B相同的子序列,且这个子序列不能改变相对顺序,只要相对顺序不改变,链接相同数字的直线就不会相交。
代码和上一题一样!

53. 最大子序和

力扣链接
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

思路

  1. 确定dp含义
    dp[i]:以nums[i]结尾的连续数组最大和为i
  2. 确定递推公式
    最大和要么是nums[i],要么是dp[i-1]+nums[i],取个max
dp[i]=max(nums[i],dp[i-1]+nums[i])
  1. 初始化
    dp[0]=nums[0],其余随便
  2. 确定递推方向
    从前到后
class Solution:def maxSubArray(self, nums: List[int]) -> int:dp = [0] * len(nums)dp[0] = nums[0]for i in range(1,len(nums)):dp[i] = max(nums[i],dp[i-1]+nums[i])return max(dp)

392.判断子序列

力扣链接
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。(可以不连续)

思路

  1. 确定dp数组
    以下标i-1结尾的字符串s和下标j-1结尾的字符串t,相同子序列长度为dp[i][j]
  2. 确定递推公式
    如果s[i - 1] == t[j - 1],dp[i][j] = dp[i-1][j-1] + 1
    否则,dp[i][j] = dp[i][j-1]
  3. 初始化
    全初始化为0
  4. 确定遍历方向
    从上到下,从左到右。

代码与最长公共子序列的差不多。

class Solution:def isSubsequence(self, s: str, t: str) -> bool:dp = [ [0]*(len(t)+1) for _ in range(len(s)+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] + 1else:dp[i][j] = max(dp[i][j-1], dp[i-1][j])return dp[-1][-1]==len(s)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com