You are given two integer arrays nums1
and nums2
. We write the integers of nums1
and nums2
(in the order they are given) on two separate horizontal lines.
We may draw connecting lines: a straight line connecting two numbers nums1[i]
and nums2[j]
such that:
nums1[i] == nums2[j]
, andNote that a connecting line cannot intersect even at the endpoints (i.e., each number can only belong to one connecting line).
Return the maximum number of connecting lines we can draw in this way.
Example 1:
Input: nums1 = [1,4,2], nums2 = [1,2,4] Output: 2 Explanation: We can draw 2 uncrossed lines as in the diagram. We cannot draw 3 uncrossed lines, because the line from nums1[1] = 4 to nums2[2] = 4 will intersect the line from nums1[2]=2 to nums2[1]=2.
Example 2:
Input: nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2] Output: 3
Example 3:
Input: nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1] Output: 2
Constraints:
1 <= nums1.length, nums2.length <= 500
1 <= nums1[i], nums2[j] <= 2000
This problem can be efficiently solved using dynamic programming. The core idea is to build a table (2D array) where each cell dp[i][j]
represents the maximum number of uncrossed lines that can be drawn considering only the first i
elements of nums1
and the first j
elements of nums2
.
Approach:
Initialization: Create a dp
table of size (m+1) x (n+1), where m
and n
are the lengths of nums1
and nums2
respectively. Initialize the first row and column to 0, as there are no uncrossed lines possible if either of the arrays is empty.
Iteration: Iterate through the dp
table from i = 1
to m
and j = 1
to n
. For each cell dp[i][j]
, consider two cases:
nums1[i-1] == nums2[j-1]: If the current elements from both arrays are equal, it means we can draw a line connecting them. The maximum number of uncrossed lines in this case will be 1 more than the number of lines we could draw using the preceding elements (dp[i-1][j-1] + 1
).
nums1[i-1] != nums2[j-1]: If the elements are not equal, we cannot draw a line connecting them. We must choose the maximum between:
dp[i-1][j]
: The maximum lines possible using the first i-1
elements of nums1
and the first j
elements of nums2
.dp[i][j-1]
: The maximum lines possible using the first i
elements of nums1
and the first j-1
elements of nums2
.Result: The final answer is stored in dp[m][n]
, which represents the maximum number of uncrossed lines possible considering all elements of both arrays.
Time Complexity: O(m*n), where 'm' and 'n' are lengths of input arrays. We iterate through the entire dp
table.
Space Complexity: O(m*n), due to the dp
table used to store intermediate results.
def maxUncrossedLines(nums1, nums2):
m, n = len(nums1), len(nums2)
dp = [[0] * (n + 1) for _ in range(m + 1)] # Initialize dp table
for i in range(1, m + 1):
for j in range(1, n + 1):
if nums1[i - 1] == nums2[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[m][n]
class Solution {
public int maxUncrossedLines(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int[][] dp = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; 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[m][n];
}
}
(Other language implementations would follow a very similar structure, just adapting syntax and standard library functions.)