当前位置: 首页 > news >正文

第九章 动态规划 part14 1143. 最长公共子序列 1035. 不相交的线 53. 最大子序和

第五十六天| 第九章 动态规划 part14 1143. 最长公共子序列 1035. 不相交的线 53. 最大子序和

一、1143. 最长公共子序列

  • 题目链接:

  • 题目介绍:

  • 思路:

    • 本题和“最长重复子数组”区别在于**这里不要求是连续的了,但要有相对顺序**,即:“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。

    • dp五部曲:

      • (1)确定dp数组及下标含义:

        • dp[i][j]:表示的是以下标i-1为结尾的text1和以下标j-1为结尾的text2的最长公共子序列的长度
          
      • (2)确定递推公式:

        • 本题不再要求连续,因此dp[i][j]可以由三个方向推出
          
        • 如果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]);
          
        • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      • (3)初始化dp数组:

        • 根据dp数组的含义,char1[0, i-1]和空数组的公共子序列长度为0;同理,char2[0, j-1]和空数组的公共子序列长度也为0。因此,dp[i][0] = 0,dp[0][j] = 0。其他位置在后续均可以覆盖,因此都初始化为0。
          
      • (4)确定遍历顺序:

        • 根据递推公式可知是正序
    • 和重复子数组(连续公共子序列)不同,本题的最终结果是在二维dp数组的最右下角,因为根据递推公式,如果不相同还是会根据左边的和上边的推导出来。

  • 代码:

class Solution {public int longestCommonSubsequence(String text1, String text2) {char[] char1 = text1.toCharArray();char[] char2 = text2.toCharArray();// (1)确定dp数组及下标含义// dp[i][j]:表示的是以下标i-1为结尾的text1和以下标j-1为结尾的text2的最长公共子序列的长度int[][] dp = new int[char1.length + 1][char2.length + 1];// (3)初始化dp数组// 根据dp数组的含义,char1[0, i-1]和空数组的公共子序列长度为0;同理,char2[0, j-1]和空数组的公共子序列长度也为0。因此,dp[i][0] = 0,dp[0][j] = 0。其他位置在后续均可以覆盖,因此都初始化为0。// (4)确定遍历顺序// 根据递推公式可知是正序for (int i = 1; i <= char1.length; i++) {for (int j = 1; j <= char2.length; j++) {// (2)确定递推公式// 本题不再要求连续,因此dp[i][j]可以由三个方向推出if (char1[i-1] == char2[j-1]) {dp[i][j] = dp[i-1][j-1] + 1;} else {dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);}}}// 和重复子数组(连续公共子序列)不同,本题的最终结果是在二维dp数组的最右下角,因为根据递推公式,如果不相同还是会根据左边的和上边的推导出来。return dp[char1.length][char2.length];}
}

二、1035. 不相交的线

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

  • 题目介绍:

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

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

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

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

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

      示例 1:

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      输入:nums1 = [1,4,2], nums2 = [1,2,4]
      输出:2
      解释:可以画出两条不交叉的线,如上图所示。 
      但无法画出第三条不相交的直线,因为从 nums1[1]=4 到 nums2[2]=4 的直线将与从 nums1[2]=2 到 nums2[1]=2 的直线相交。
      
  • 思路:

    • 套壳的“最长公共子序列”
    • 思路和解法与上道题目是一样的
  • 代码:

class Solution {public int maxUncrossedLines(int[] nums1, int[] nums2) {int[][] dp = new int[nums1.length + 1][nums2.length + 1];for (int i = 1; i <= nums1.length; i++) {for (int j = 1; j <= nums2.length; j++) {if (nums1[i-1] == nums2[j-1]) {dp[i][j] = dp[i-1][j-1] + 1;} else {dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);}}}return dp[nums1.length][nums2.length];}
}

三、53. 最大子序和

  • 题目链接:https://leetcode.cn/problems/maximum-subarray

  • 题目介绍:

    • 相关企业

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

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

      示例 1:

      输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
      输出:6
      解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
      
  • 思路:

    • dp五部曲:

      • (1)确定dp数组及下标含义

        • dp[i]:表示的是以nums[i]为结尾的最大连续子序列之和
          
      • (2)确定递推公式

        • dp[i]只能由两个方向推出来:一个是:因为是连续的所以是dp[i-1] + nums[i]另一个是:当前nums[i]
          
      • (3)初始化dp数组

        • dp[0]:表示的是以nums[0]为结尾的最大连续子序列的和,所以dp[0] = nums[0]
          
      • (4)遍历顺序:正序

  • 代码:

class Solution {public int maxSubArray(int[] nums) {if (nums == null || nums.length == 0) return 0;int result = nums[0];// (1)确定dp数组及下标含义// dp[i]:表示的是以nums[i]为结尾的最大连续子序列之和int[] dp = new int[nums.length];// (3)初始化dp数组// dp[0]:表示的是以nums[0]为结尾的最大连续子序列的和,所以dp[0] = nums[0].dp[0] = nums[0];// (4)遍历顺序:正序for (int i = 1; i < nums.length; i++) {// (2)确定递推公式// dp[i]只能由两个方向推出来://     一个是:因为是连续的所以是dp[i-1] + nums[i]//     另一个是:当前nums[i]dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);if (dp[i] > result) result = dp[i];}return result;}
}

总结:

  • 子数组:求解的就是**连续子序列**
  • 子序列:没有强调的连续,只要是子序列即可
http://www.lryc.cn/news/181785.html

相关文章:

  • 腾讯云服务器南京地域详细介绍、测试IP和Ping值测速
  • 理解CSS的层叠性和继承性
  • OSI体系结构和TCP/IP体系结构
  • 侯捷 C++ STL标准库和泛型编程 —— 8 适配器
  • 每日一题 416 分割等和子集(01背包)
  • U盘插上就显示让格式化是坏了吗?
  • 分布式应用程序协调服务 ZooKeeper 详解
  • Anniversary party(树形dp 基础题)
  • Junit的常用操作
  • Elasticsearch安装并使用Postman访问
  • Pytorch深度学习训练模型保存问题,找不到保存路径
  • 数据结构与算法之堆: Leetcode 23. 合并 K 个升序链表 (Typescript版)
  • 代码随想录算法训练营第五十七天 | 392.判断子序列 115.不同的子序列
  • Kafka日志索引详解以及生产常见问题分析与总结
  • vue中 css scoped原理
  • tf.compat.v1.global_variables()
  • 登录注册实现
  • Push rejected: Push to origin/master was rejected
  • 在线OJ项目核心思路
  • Spring MVC:数据绑定
  • STM32CubeMX学习笔记-USB接口使用(HID按键)
  • C#,数值计算——Ranq2的计算方法与源程序
  • C/C++ 数据结构 - 链表
  • 【算法基础】一文掌握十大排序算法,冒泡排序、插入排序、选择排序、归并排序、计数排序、基数排序、希尔排序和堆排序
  • javascript二维数组(3):指定数组元素的特定属性进行搜索
  • 使用Qt进行HTTP通信的方法
  • 第45节——页面中修改redux里的数据
  • 软考 系统架构设计师系列知识点之软件架构风格(2)
  • 【C++11】Lambda 表达式:基本使用 和 底层原理
  • 【网络安全---ICMP报文分析】Wireshark教程----Wireshark 分析ICMP报文数据试验