• 代码随想录训练营day53, 最长公共子序列, 不相交的线, 最大子序和


    最长公共子序列

    这里的区别就是, 这里不要求是连续的了, 但要有相对顺序

    1. dp[i][j], 长度为[0,i-1]的字符串text1与长度为[0,j-1]的字符串text2的最长公共子序列为dp[i][j]

    (这里和上一题一样, 也是要-1)

    1. 递推: 有两种情况:

      1. text1[i-1]和text2[j-1]相等, 那么dp[i-1]dp[j-1]+1
      2. text1[i-1]和text2[j-1]不相等, 那么取max(dp[i-1][j], dp[i][j-1])

      (两个字符串各退一位, 去之前能匹配到的最大长度)

    2. 初始化: 和上题一样, 必须是为0

    1. class Solution {
    2. public int longestCommonSubsequence(String text1, String text2) {
    3. int len1 = text1.length();
    4. int len2 = text2.length();
    5. int[][] dp = new int[len1 + 1][len2 + 1];
    6. //记住定义是i-1, j-1
    7. //由于-1, 所以要<=len
    8. for(int i = 1; i <= len1; i++){
    9. for(int j = 1; j <= len2; j++){
    10. //现在是字符串哦
    11. if(text1.charAt(i - 1) == text2.charAt(j - 1)){
    12. //第一种情况
    13. dp[i][j] = dp[i - 1][j - 1] + 1;
    14. } else {
    15. dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
    16. }
    17. }
    18. }
    19. //因为dp数组定义式长度为i-1/j-1的,
    20. return dp[len1][len2];
    21. }
    22. }

    不相交的线

    写下AB两个数组, 如果相同就连线

    分析:

    本题说是求绘制的最大连线数, 其实就是求两个字符串的最长公共子序列的长度, 那么这道题和上一题是一模一样的(这里甚至都不需要用charAt)

    1. class Solution {
    2. public int maxUncrossedLines(int[] nums1, int[] nums2) {
    3. //日🐴代码是一模一样的
    4. int len1 = nums1.length;
    5. int len2 = nums2.length;
    6. int[][] dp = new int[len1 + 1][len2 + 1];
    7. for(int i = 1;i <= len1; i++){
    8. for(int j = 1; j <= len2; j++){
    9. if(nums1[i - 1] == nums2[j - 1]){
    10. dp[i][j] = dp[i - 1][j - 1] + 1;
    11. } else {
    12. dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
    13. }
    14. }
    15. }
    16. return dp[len1][len2];
    17. }
    18. }

    最大子序和

    这道题之前做过

    贪心:

    遍历数组, 只取所有的正数, 如果当前连续和count为负数, 就直接舍弃从头开始

    1. class Solution {
    2. public int maxSubArray(int[] nums) {
    3. int res = Integer.MIN_VALUE;
    4. int count = 0;
    5. for(int i = 0; i < nums.length; i++){
    6. count += nums[i];
    7. res = Math.max(count, res);
    8. //如果为负数, 就直接舍弃
    9. if(count < 0){
    10. count = 0;
    11. }
    12. }
    13. return res;
    14. }
    15. }

    动规: 

    1. 数组定义: 包括下标i之前的最大连续子序列和尾dp[i]

    2. 递推: 其实原理也是一样的, 两个方向推出来

      1. dp[i-1] + nums[i]
      2. nums[i], 从头开始计算

      (取最大的)

    3. 初始化: dp[0]=nums[0]

    4. 最终直接return最大的dp[i]

    (细节: 由于他这里问的不是有几个, 而是sum, 所以res就不能随便取了)

    1. class Solution {
    2. public int maxSubArray(int[] nums) {
    3. int[] dp = new int[nums.length + 1];
    4. //这里res定义第一个数, 如果只有一个数的话那就是res
    5. int res = nums[0];
    6. dp[0] = nums[0];
    7. for(int i = 1; i < nums.length; i++){
    8. //要么增加, 要么从头开始
    9. dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
    10. //要放在循环内, 不断取最大值
    11. if(dp[i] > res){
    12. res = dp[i];
    13. }
    14. }
    15. return res;
    16. }
    17. }

  • 相关阅读:
    如何恢复被.carver勒索病毒加密的数据?
    springboot+清远旅游推荐网站 毕业设计-附源码211551
    transformer
    微信小程序实战,基于vue2实现瀑布流
    c++征途 --- 函数提高
    Docker基础组件、安装启动和Docker生命周期
    【web前端期末大作业】html网上在线书城大学生静态网页 大学生html当当书城仿站 网上书城购物网页作业HTML
    RPA前景、要求和学习方向
    设计模式之装饰者模式
    springboot+基于web的传染病信息管理系统的设计与实现 毕业设计-附源码221124
  • 原文地址:https://blog.csdn.net/Southside3amurai/article/details/128168995