You have been given an array/list “pairs” of ‘N’ pairs of integers. In every pair, the first number is always smaller than the second number. A pair (a, b) can follow another pair (c, d) in a chain if a > d. Now you are supposed to find the length of the longest chain which can be formed.
You can select pairs in any order.
The first line contains an integer ‘T’ denoting the number of test cases. Then each test case is as follows.
The first input line of each test case contains an integer ‘N’ which denotes the number of pairs.
Next ‘N’ lines contain two space-separated integers denoting a pair.
Output Format :
For each test case, print the length of the longest chain which can be formed.
Print the output of each test case in a separate line.
Note:
You are not required to print the expected output; it has already been taken care of. Just implement the function.
1 <= T <= 50
1 <= N <= 1000
0 <= pairs[i][0], pairs[i][1] <= 10^6
Time limit: 1 sec
2
2
3 6
4 5
2
2 4
6 9
1
2
For the first test case, one of the longest chains is (3, 6) of length 1.
For the second test case, the longest chain is (2, 4) -> (6, 9) and its length is 2.
2
3
1 2
2 3
3 4
1
7 8
2
1
Can you think of breaking the problem into sub-problems?
The basic idea of this approach is to break the original problem into sub-problems. Let us sort the array/list of pairs by the first integer in non-decreasing order and define a recursive function
getLength(int i)
Which returns the length of the longest chain which ends at pairs[i]. As per given in the problem statement pair[i] can follow a pair[j] (for any integer ‘j’) if pairs[i][0] > pairs[j][1]. Since the array/list is sorted in nondecreasing order and also it is given that the second integer is always greater than the first integer in any pair, ‘j’ must be less than ‘i’.
Therefore, we can define getLength(i) = max(getLength(i), getLength(j) + 1) if j < i and ( pairs[i][0] > pairs[j][1] ) holds true.
Now, consider the following steps to implement getLength(i) :
O(2 ^ N), Where ‘N’ is the number of pairs in the given array/list.
Since we are using a recursive function which can be defined as f(n) = f(n - 1) + f(n - 2) + . . . + f(1) in the worst case. So the few steps of finding the complexity are below
First, look at the problem as :
F(N) = a F(N - 1) + c So,
F(1) = a * F(0) + c = a + c
F(2) = a * F(1) + c = a*a + a * c + c
F(3) = a * F(2) + c = a * a * a + a * a * c + a * c + cNote that this creates a pattern. specifically:
F(N) = sum(a ^ j c ^ (n - j), j = 0, ..., N)Put c = 1 gives,
F(N) = sum(a ^ j, j = 0, ..., N)This is a geometric series, which evaluates to :
F(N) = (1 - a ^ (N + 1)) / (1 - a)
= (1 / (1 - a)) - (1 / (1 - a)) a ^ N
= (1 / (a - 1))(-1 + a ^ (N + 1))
For N >= 0.
Note that this formula is the same as given above for c=1 using the z-transform method.
Again, O(a ^ N). Put a = 2 because our problem split into two sub-problems. So overall time complexity will be O(2 ^ N).
O(N), where ‘N’ is the number of pairs.
Since we are using a recursive function where there may be ‘N’ states present in the recursive call stack in the worst case. So the overall space complexity will be O(N).