You are given an array of n
pairs pairs
where pairs[i] = [lefti, righti]
and lefti < righti
.
A pair p2 = [c, d]
follows a pair p1 = [a, b]
if b < c
. A chain of pairs can be formed in this fashion.
Return the length longest chain which can be formed.
You do not need to use up all the given intervals. You can select pairs in any order.
Example 1:
Input: pairs = [[1,2],[2,3],[3,4]] Output: 2 Explanation: The longest chain is [1,2] -> [3,4].
Example 2:
Input: pairs = [[1,2],[7,8],[4,5]] Output: 3 Explanation: The longest chain is [1,2] -> [4,5] -> [7,8].
Constraints:
n == pairs.length
1 <= n <= 1000
-1000 <= lefti < righti <= 1000
This problem asks to find the length of the longest chain that can be formed from a given set of pairs, where a pair (c, d)
follows another pair (a, b)
if b < c
. This suggests a greedy approach or dynamic programming. The most efficient solution uses a greedy strategy combined with sorting.
Sort by End Time: The core idea is to sort the pairs based on their second element (the right endpoint). Sorting ensures that we consider pairs in a way that allows us to extend chains efficiently. We sort in ascending order of the right endpoints ( right_i
).
Iterative Greedy Selection: We iterate through the sorted pairs. We maintain a variable pre
to keep track of the end time of the last selected pair in the current chain.
Chain Extension: For each pair [left_i, right_i]
, we check if its start time (left_i
) is greater than the end time of the last selected pair (pre
). If it is, it means we can extend the current chain. We increment the chain length (ans
) and update pre
to right_i
to reflect the new end time of the extended chain.
Return Length: After processing all pairs, the value of ans
represents the length of the longest chain formed.
The code examples below demonstrate the solution in several popular programming languages. The core logic remains consistent across all languages.
class Solution:
def findLongestChain(self, pairs: List[List[int]]) -> int:
# Sort pairs by the second element (end time)
pairs.sort(key=lambda x: x[1])
ans = 0 # Length of the longest chain
pre = float('-inf') # End time of the last selected pair (initialized to negative infinity)
for a, b in pairs: # Iterate through the sorted pairs
if pre < a: # Check if the current pair's start time is greater than the previous pair's end time
ans += 1 # Extend the chain
pre = b # Update the end time of the last selected pair
return ans
class Solution {
public int findLongestChain(int[][] pairs) {
Arrays.sort(pairs, (a, b) -> Integer.compare(a[1], b[1])); // Sort by the second element
int ans = 0; // Length of the longest chain
int pre = Integer.MIN_VALUE; // End time of the last selected pair
for (int[] p : pairs) { // Iterate through the sorted pairs
if (pre < p[0]) { // Check if the current pair can extend the chain
ans++; // Extend the chain
pre = p[1]; // Update the end time
}
}
return ans;
}
}
The other languages (C++, Go, TypeScript, Rust) follow a very similar structure, differing only in syntax and specific library functions used for sorting and comparison. The core algorithmic idea remains the same.