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

题目

1035. 不相交的线

中等

相关标签

数组 动态规划

在两条独立的水平线上按给定的顺序写下 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 的直线相交。

示例 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<vector<int>> dp(A.size() + 1, vector<int>(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++ 代码

cpp 复制代码
class Solution {
public:
    int maxUncrossedLines(vector<int>& A, vector<int>& B) {
        // 创建一个二维数组dp,用于记录A和B中不相交线的最大数量
        vector<vector<int>> dp(A.size() + 1, vector<int>(B.size() + 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]) { // 如果当前数字相等,表示可以连接一条不相交线
                    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()]; // 返回不相交线的最大数量
    }
};

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],即最大不相交线段数量。
java 复制代码
class Solution {
    public int maxUncrossedLines(int[] nums1, int[] nums2) {
        int len1 = nums1.length; // 数组nums1的长度
        int len2 = nums2.length; // 数组nums2的长度
        int[][] dp = new int[len1 + 1][len2 + 1]; // 创建一个大小为(len1+1)*(len2+1)的二维数组dp,用于存储最大不相交线段数量,默认初值为0

        for (int i = 1; i <= len1; i++) { // 遍历数组nums1,从第一个元素到最后一个元素
            for (int j = 1; j <= len2; j++) { // 遍历数组nums2,从第一个元素到最后一个元素
                if (nums1[i - 1] == nums2[j - 1]) { // 如果nums1中第i个元素等于nums2中第j个元素,则可以将这个元素作为一条不相交的线段
                    dp[i][j] = dp[i - 1][j - 1] + 1; // 更新dp[i][j]的值,dp[i][j]表示以nums1的前i个元素和nums2的前j个元素结尾的最大不相交线段数量
                } else {
                    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]的较大值
                }
            }
        }

        return dp[len1][len2]; // 返回最大不相交线段数量
    }
}

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

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

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

相关推荐
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou3 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
冰帝海岸4 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象4 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
‘’林花谢了春红‘’4 小时前
C++ list (链表)容器
c++·链表·list
没书读了5 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王5 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康5 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud