Problem statement
You are given
n
pairs of numbers. In every pair, the first number is always smaller than the second number.Now, we define a pair
(c, d)
can follow another pair(a, b)
if and only ifb < c
. Chain of pairs can be formed in this fashion.Given a set of pairs, find the length longest chain which can be formed. You needn‘t use up all the given pairs. You can select pairs in any order.
Example 1:
Input: [[1,2], [2,3], [3,4]] Output: 2 Explanation: The longest chain is [1,2] -> [3,4]Note:
- The number of given pairs will be in the range [1, 1000].
Solution one: Greedy algorithm
The first solution is greedy algorithm.
- Sort the pairs by the increasing order of end value.
- Keep a value of minimum end value.
- Update the minimum end value if current pair and next pair are overlapped.
- count number + 1 if the start value of next pairis greater than minimum end and update the minimum end.
Time complexity is O(n). space complexity is O(1).
class Solution { public: int findLongestChain(vector<vector<int>>& pairs) { sort(pairs.begin(), pairs.end(), [](vector<int> l, vector<int> r) { if(l[0] == r[0]){ return l[1] < r[1];} return l[0] < r[0];}); int len = 1; int min_end = pairs[0][1]; for(int i = 1; i < pairs.size(); i++){ if(min_end >= pairs[i][1]){ min_end = pairs[i][1]; } else if(min_end < pairs[i][0]){ len++; min_end = pairs[i][1]; } } return len; } };
Another concise version of solution one.
- Since all pairs are sorted, we just need to find the first non-overlapped pair with current pair.
- Count number + 1 and update the current pair.
Time complexity is O(n). Space complexity is O(1).
class Solution { public: int findLongestChain(vector<vector<int>>& pairs) { // sort the pair by increasing order according to the end sort(pairs.begin(), pairs.end(), [](vector<int> l, vector<int> r) { return l[1] < r[1]; }); int len = 1; for(int i = 0, j = 1; j < pairs.size(); j++){ if(pairs[i][1] < pairs[j][0]){ len++; i = j; } } return len; } };
Solution two: DP.
It is similar with 300. Longest Increasing Subsequence.
For each element, dp[i], we need loop back from all previous elements to find the solution.
Meanwhile, update the dp[i] and find the maximum length.
Time complexity is O(n * n), space complexity is O(n). Obviously dp solution for this problem is not optimal, but it is still worth to learn how to deduce the dp formula.
class Solution { public: int findLongestChain(vector<vector<int>>& pairs) { // sort the pair by increasing order according to the end sort(pairs.begin(), pairs.end(), [](vector<int> l, vector<int> r) { return l[1] < r[1]; }); int size = pairs.size(); int dp[size] = {1}; int max_len = 1; for(int i = 1; i < pairs.size(); i++){ for(int j = 0; j < i; j++){ if(pairs[j][1] < pairs[i][0]){ dp[i] = max(dp[i], dp[j] + 1); } } max_len = max(max_len, dp[i]); } return max_len; } };