• 代码随想录 动态规划 14


    1143. 最长公共子序列

    给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

    一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

    • 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

    两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列

    思路:设置二维dp数组 dp[i][j] 表示 text1 前 i-1 个字母 和 text2 前 j - 1个字母结尾 的最长公共子序列。转移方程为,当 text1[i-1] == text2[j-1] 时,dp[i][j] = dp[i-1][j-1] ,  当text1[i-1] != text2[j-1] 时,dp[i][j] = max(dp[i-1][j], dp[i][j-1]). 因为dp[i][j] 依赖dp[i-1][j], dp[i][j-1],所以用倒序做一维dp不方便。

    二维dp

    1. class Solution:
    2. def longestCommonSubsequence(self, text1: str, text2: str) -> int:
    3. dp = [[0] * (len(text2) + 1) for _ in range(len(text1) + 1)]
    4. for i in range(1, len(text1) + 1):
    5. for j in range(1, len(text2) + 1):
    6. if text1[i-1] == text2[j-1]:
    7. dp[i][j] = dp[i-1][j-1] + 1
    8. else:
    9. dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    10. return dp[-1][-1]

     

    1035. 不相交的线

     

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

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

    •  nums1[i] == nums2[j]
    • 且绘制的直线不与任何其他连线(非水平线)相交。

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

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

    不相交的线其实本质上就是最长公共子序列

    一维dp:使用prev来记录dp[j-1]的原值(相当于dp[i-1][j-1]), curr记录dp[j]的原值(相当于dp[i-1][j])

    1. class Solution:
    2. def maxUncrossedLines(self, nums1: List[int], nums2: List[int]) -> int:
    3. m, n = len(nums1), len(nums2)
    4. dp = [0] * (n + 1) # 初始化一维DP数组
    5. for i in range(1, m + 1):
    6. prev = dp[i][0] # 保存上一个位置的最长公共子序列长度
    7. for j in range(1, n + 1):
    8. curr = dp[j] # 保存当前位置的最长公共子序列长度
    9. if nums1[i - 1] == nums2[j - 1]:
    10. # 如果当前字符相等,则最长公共子序列长度加一
    11. dp[j] = prev + 1
    12. else:
    13. # 如果当前字符不相等,则选择保留前一个位置的最长公共子序列长度中的较大值
    14. dp[j] = max(dp[j], dp[j - 1])
    15. prev = curr # 更新上一个位置的最长公共子序列长度
    16. return dp[n] # 返回最后一个位置的最长公共子序列长度作为结果

    53. 最大子数组和

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

    子数组 是数组中的一个连续部分

    思路:dp[i]的定义为,前i个元素的最大和的连续子数组。转移方程为 dp[i] = max( dp[i-1], nums[i]), 使用result记录最大值

    1. class Solution:
    2. def maxSubArray(self, nums: List[int]) -> int:
    3. dp = [0] * len(nums)
    4. dp[0] = nums[0]
    5. result = dp[0]
    6. for i in range(1, len(nums)):
    7. dp[i] = max(dp[i-1] + nums[i], nums[i]) #状态转移公式
    8. result = max(result, dp[i]) #result 保存dp[i]的最大值
    9. return result

  • 相关阅读:
    幂等性解决方案
    springboot校园失物招领网站系统在线视频点播系统毕业设计毕设作品开题报告开题答辩PPT
    【C++】多态
    Android studio 迁移之后打开没反应
    python七大爬虫程序
    信任营销已成为产品消费蓝海,开利网络与合作伙伴共建信任营销闭环
    Kubeadm部署K8s
    Azure Function 时区设置
    【Flutter小记10】apk 提交各大应用市场,出现armeabi与arm64 版本标识/版本号不一致无法上传审核的解决方案
    Azure - 机器学习:自动化机器学习中计算机视觉任务的超参数
  • 原文地址:https://blog.csdn.net/Atuosi/article/details/133513439