• 力扣第1035题 不相交的线中等 c++ (最长公共子序列) 动态规划 附Java代码


    题目

    1035. 不相交的线

    中等

    相关标签

    数组   动态规划

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

    现在,可以绘制一些连接两个数字 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 的直线相交。
    

    示例 2:

    输入:nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
    输出:3
    

    示例 3:

    输入:nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
    输出:2

    提示:

    • 1 <= nums1.length, nums2.length <= 500
    • 1 <= nums1[i], nums2[j] <= 2000

    思路和解题方法

    • vector> dp(A.size() + 1, vector(B.size() + 1, 0));:创建一个二维数组dp,用于记录A和B中不相交线的最大数量。其中,第一维表示A数组的长度加1,第二维表示B数组的长度加1,初始值为0。
    • for (int i = 1; i <= A.size(); i++):从第二个数字开始遍历A数组,因为需要与前一个数字比较。
    • for (int j = 1; j <= B.size(); j++):从第二个数字开始遍历B数组,因为需要与前一个数字比较。
    • if (A[i - 1] == B[j - 1]):如果当前数字相等,表示可以连接一条不相交线,在不相交线的基础上再加1,更新不相交线的数量。此处的i-1j-1是因为dp数组从下标1开始计算,而A和B数组从下标0开始计算。
    • dp[i][j] = dp[i - 1][j - 1] + 1;:如果当前数字相等,更新不相交线的数量。
    • else:如果当前数字不相等。
    • dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);:取前一行或前一列的最大值作为不相交线的数量。
    • return dp[A.size()][B.size()];:返回不相交线的最大数量。

    复杂度

            时间复杂度:

                    O(mn)

    时间复杂度是O(mn),其中m和n分别是数组A和B的长度。因为要遍历A和B中的所有数字,并对每个数字进行比较和操作。

            空间复杂度

                    O(mn)

    空间复杂度也是O(mn),因为需要创建一个二维数组dp来记录不相交线的最大数量。其中,第一维是A数组的长度加1,第二维是B数组的长度加1。

    c++ 代码

    1. class Solution {
    2. public:
    3. int maxUncrossedLines(vector<int>& A, vector<int>& B) {
    4. // 创建一个二维数组dp,用于记录A和B中不相交线的最大数量
    5. vectorint>> dp(A.size() + 1, vector<int>(B.size() + 1, 0));
    6. for (int i = 1; i <= A.size(); i++) { // 遍历A数组
    7. for (int j = 1; j <= B.size(); j++) { // 遍历B数组
    8. if (A[i - 1] == B[j - 1]) { // 如果当前数字相等,表示可以连接一条不相交线
    9. dp[i][j] = dp[i - 1][j - 1] + 1; // 更新不相交线的数量
    10. }
    11. else {
    12. dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); // 如果当前数字不相等,取前一行或前一列的最大值作为不相交线的数量
    13. }
    14. }
    15. }
    16. return dp[A.size()][B.size()]; // 返回不相交线的最大数量
    17. }
    18. };

    Java代码

    • 创建一个大小为(len1+1)*(len2+1)的二维数组dp,用于存储最大不相交线段数量,默认初值为0。
    • 遍历数组nums1和nums2,从第一个元素到最后一个元素。在循环中,根据当前元素的相等与否来更新dp[i][j]的值。如果nums1中第i个元素等于nums2中第j个元素,则可以将这个元素作为一条不相交的线段,更新dp[i][j]的值为dp[i-1][j-1] + 1。如果nums1中第i个元素不等于nums2中第j个元素,则最大不相交线段数量取决于dp[i-1][j]和dp[i][j-1]的较大值。
    • 最后,返回dp[len1][len2],即最大不相交线段数量。
    1. class Solution {
    2. public int maxUncrossedLines(int[] nums1, int[] nums2) {
    3. int len1 = nums1.length; // 数组nums1的长度
    4. int len2 = nums2.length; // 数组nums2的长度
    5. int[][] dp = new int[len1 + 1][len2 + 1]; // 创建一个大小为(len1+1)*(len2+1)的二维数组dp,用于存储最大不相交线段数量,默认初值为0
    6. for (int i = 1; i <= len1; i++) { // 遍历数组nums1,从第一个元素到最后一个元素
    7. for (int j = 1; j <= len2; j++) { // 遍历数组nums2,从第一个元素到最后一个元素
    8. if (nums1[i - 1] == nums2[j - 1]) { // 如果nums1中第i个元素等于nums2中第j个元素,则可以将这个元素作为一条不相交的线段
    9. dp[i][j] = dp[i - 1][j - 1] + 1; // 更新dp[i][j]的值,dp[i][j]表示以nums1的前i个元素和nums2的前j个元素结尾的最大不相交线段数量
    10. } else {
    11. dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); // 如果nums1中第i个元素不等于nums2中第j个元素,则最大不相交线段数量取决于dp[i-1][j]和dp[i][j-1]的较大值
    12. }
    13. }
    14. }
    15. return dp[len1][len2]; // 返回最大不相交线段数量
    16. }
    17. }

    觉得有用的话可以点点赞,支持一下。

    如果愿意的话关注一下。会对你有更多的帮助。

    每天都会不定时更新哦  >人<  。

  • 相关阅读:
    【深入解析spring cloud gateway】04 Global Filters
    【MyBatis篇】MyBatis框架基础知识笔记
    MySQL之索引知多少
    专访 Web3Go 新产品 Reiki:培育 AI 原生数字资产与创意新土壤
    C语言中大小写字母转换
    每日OJ题_其它背包问题④_力扣96. 不同的二叉搜索树(卡特兰数)
    亚商投资顾问 早餐FM/1103联储连续第四次加息75个基点
    总结——》【Redis】
    【uniapp】subnvue组件数据更新视图未更新问题
    【编程题】【Scratch四级】2021.03 绳子算法
  • 原文地址:https://blog.csdn.net/jgk666666/article/details/134213706