Uncrossed Lines

Uncrossed Lines

Leetcode Daily Challenge (11th May, 2023)

Problem Statement:-

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], and

  • the line we draw does not intersect any other connecting (non-horizontal) line.

Note 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.

Link: https://leetcode.com/problems/uncrossed-lines/description/

Problem Explanation with examples:-

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
Explanation: There can only be 3 connections without crossing the lines. nums1[0]=2 connects to nums2[2]=2, nums1[1]=5 connects to nums2[4]=5, and nums1[3]=2 connects to nums2[5]=2.

Example 3

Input: nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
Output: 2
Explanation: There can only be 2 connections without crossing the lines. nums1[0]=1 connects to nums2[4]=1, and nums1[5]=5 connects to nums2[3]=5.

Constraints

  • 1 <= nums1.length, nums2.length <= 500

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

Intuition:-

  • If one element connects to some equal in the other array then the indexes previous to that element in both the arrays are of no more use to us.

  • We can use dp by keeping a pointer in both arrays and then we can either connect an equal element or we can skip the element in the first array.

Solution:-

  • Take the length of both the arrays in variables m and n.

  • Define a function solve(i,j) which returns the maximum number of lines that can be drawn without crossing each other if we start from index i in the first array and index j in the second array.

  • If i >= m or j >= n then return 0.

  • Keep a variable mx to store the maximum number of lines that can be drawn.

  • Loop over from j to n and check if nums1[i] == nums2[z] then update mx = max(mx,1+solve(i+1,z+1)).

  • Update mx = max(mx,solve(i+1,j)) to account for the case when we skip the element in the first array.

  • Return mx.

Code:-

JAVA Solution

class Solution {
    public int maxUncrossedLines(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        HashMap<String, Integer> memo = new HashMap<>();

        return solve(nums1, nums2, 0, 0, memo);
    }

    private int solve(int[] nums1, int[] nums2, int i, int j, HashMap<String, Integer> memo) {
        if (i >= nums1.length || j >= nums2.length) {
            return 0;
        }

        String key = i + "," + j;
        if (memo.containsKey(key)) {
            return memo.get(key);
        }

        int mx = 0;
        for (int z = j; z < nums2.length; z++) {
            if (nums1[i] == nums2[z]) {
                mx = Math.max(mx, 1 + solve(nums1, nums2, i + 1, z + 1, memo));
            }
        }

        mx = Math.max(mx, solve(nums1, nums2, i + 1, j, memo));

        memo.put(key, mx);
        return mx;
    }
}

Python Solution

class Solution:
    def maxUncrossedLines(self, nums1: List[int], nums2: List[int]) -> int:
        m = len(nums1)
        n = len(nums2)
        @cache
        def solve(i,j):
            if i >= m or j >= n:
                return 0
            mx = 0
            for z in range(j,n):
                if nums1[i] == nums2[z]:
                    mx = max(mx,1+solve(i+1,z+1))

            mx = max(mx,solve(i+1,j))

            return mx

        return solve(0,0)

Complexity Analysis:-

TIME:-

The time complexity is O(m*n), where m and n are the lengths of nums1 and nums2, respectively. This is because we have to evaluate the function for all possible i and j values between 0 and m-1 and n-1, respectively.

SPACE:-

The space complexity is O(mn)*, due to the use of memoization using the @cache decorator. The cache will store the results of all unique (i,j) combinations, which can be at most m*n.

References:-

Connect with me:-

Did you find this article valuable?

Support Leeting-LCS by becoming a sponsor. Any amount is appreciated!