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:
nums1 = [1,4,2], nums2 = [1,2,4]
Output: 2
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:
nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
Output: 3
Example 3:
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
The problem asks us to find the maximum number of non-intersecting lines that can be drawn between two integer arrays, nums1
and nums2
. A line can be drawn between nums1[i]
and nums2[j]
if nums1[i] == nums2[j]
, and no two lines can intersect. This problem can be solved using dynamic programming by recognizing it as a variation of the Longest Common Subsequence (LCS) problem.
We could try all possible combinations of lines, checking for intersections, and keeping track of the maximum number of non-intersecting lines found. This approach would be extremely inefficient due to the exponential number of combinations that need to be checked.
We can solve this problem efficiently using dynamic programming. Let dp[i][j]
represent the maximum number of connecting lines we can draw between nums1[0...i]
and nums2[0...j]
. The base case is dp[0][j] = 0
and dp[i][0] = 0
for all i
and j
. The recurrence relation is as follows:
nums1[i] == nums2[j]
, then dp[i][j] = dp[i-1][j-1] + 1
(we can draw a line).nums1[i] != nums2[j]
, then dp[i][j] = max(dp[i-1][j], dp[i][j-1])
(we either skip nums1[i]
or nums2[j]
).By filling the dp
table in a bottom-up manner, we can find the maximum number of connecting lines at dp[nums1.length][nums2.length]
.
def maxUncrossedLines(nums1, nums2):
n1 = len(nums1)
n2 = len(nums2)
dp = [[0] * (n2 + 1) for _ in range(n1 + 1)]
for i in range(1, n1 + 1):
for j in range(1, n2 + 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[n1][n2]
# Example usage:
nums1 = [1,4,2]
nums2 = [1,2,4]
print(maxUncrossedLines(nums1, nums2)) # Output: 2
nums1 = [2,5,1,2,5]
nums2 = [10,5,2,1,5,2]
print(maxUncrossedLines(nums1, nums2)) # Output: 3
nums1 = [1,3,7,1,7,5]
nums2 = [1,9,2,5,1]
print(maxUncrossedLines(nums1, nums2)) # Output: 2
The time complexity is O(m * n), where 'm' is the length of nums1
and 'n' is the length of nums2
. This is because we iterate through each cell of the dp
table, which has dimensions (m+1) x (n+1).
The space complexity is O(m * n) because we use a 2D array dp
of size (m+1) x (n+1) to store the intermediate results. The space used by the dp
table dominates the space complexity.
nums1
or nums2
is empty, the result will be 0, which is handled correctly by the base cases in the dynamic programming approach.nums1
and nums2
, the result will be 0, which will be correctly computed because the dp
table will remain filled with 0s.