题目
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<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-1
和j-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++ 代码
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],即最大不相交线段数量。
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]; // 返回最大不相交线段数量
}
}
觉得有用的话可以点点赞,支持一下。
如果愿意的话关注一下。会对你有更多的帮助。
每天都会不定时更新哦 >人< 。