AlgoMaster Logo

Maximum Length of Pair Chain

mediumFrequencyUpdated September 21, 2026

Understanding the Problem

This problem is about selecting the maximum number of pairs that can form a chain, where each pair's start must be strictly greater than the previous pair's end. We can pick pairs in any order, not just the order they appear in the input, so we are free to sort or rearrange them however we like.

This is the activity selection problem in different clothing. Activity selection asks: given a set of activities with start and end times, find the maximum number of non-overlapping activities. Each pair [a, b] is an interval, and the chain condition b < c means the next pair must start strictly after the previous one ends (no overlap, and not even touching endpoints).

Key Constraints:

  • 1 <= n <= 1000 -> With n up to 1,000, an O(n^2) solution does about 1 million operations, which runs well within typical time limits. So even the O(n^2) DP below is fast enough.
  • -1000 <= left_i < right_i <= 1000 -> The values fit comfortably in a 32-bit integer, so there is no overflow concern. Each pair has left < right, so there are no zero-length intervals to worry about.
  • "You can select pairs in any order" -> Because order is free, sorting the input is allowed and is what makes both approaches below work.

Approach 1: Dynamic Programming

Intuition

Building a chain is structurally the same as building a Longest Increasing Subsequence (LIS), except that instead of comparing single values we compare intervals. A pair can extend a chain only if it starts after the previous pair ends.

Sort the pairs by their first element, then for each pair look at all previous pairs and check whether they can precede it. If pair j can precede pair i (meaning pairs[j][1] < pairs[i][0]), then the longest chain ending at i is at least one more than the longest chain ending at j. Sorting by the first element guarantees every pair that could precede i appears before i in the array, so a single left-to-right scan considers all candidates.

Algorithm

  1. Sort pairs by the first element.
  2. Create a dp array where dp[i] represents the length of the longest chain ending with pairs[i].
  3. Initialize every dp[i] = 1 (each pair alone forms a chain of length 1).
  4. For each pair i, look at all pairs j < i. If pairs[j][1] < pairs[i][0], then dp[i] = max(dp[i], dp[j] + 1).
  5. Return the maximum value in the dp array.

Example Walkthrough

Input:

0
1
0
1
2
1
2
3
2
3
4
pairs

The pairs are already sorted by first element. We initialize dp = [1, 1, 1], then fill it left to right.

i = 1 (pair [2,3]): check j = 0 (pair [1,2]). Is pairs[0][1] < pairs[1][0], that is 2 < 2? No, the endpoints touch but the chain needs a strict gap. So dp[1] stays 1.

i = 2 (pair [3,4]): check j = 0 (pair [1,2]). Is 2 < 3? Yes, so dp[2] = max(1, dp[0] + 1) = 2. Then check j = 1 (pair [2,3]). Is 3 < 3? No. So dp[2] stays 2.

0
1
1
1
2
2
dp

The longest chain ending at index 2 has length 2, formed by [1,2] -> [3,4]. The answer is max(dp) = 2.

Code

The nested loop computes the best chain ending at every individual pair, but the problem only asks for the overall maximum length. Because this is the activity selection problem, a greedy choice removes that extra work and brings the running time down to O(n log n).

Approach 2: Greedy (Sort by End)

Intuition

The greedy strategy for activity selection is to sort the intervals by their end value, then scan left to right and pick each interval whose start comes after the end of the last interval picked. Picking the pair that ends earliest leaves the most room on the number line for the remaining pairs, which is why it never hurts to take it.

Algorithm

  1. Sort pairs by the second element (end value).
  2. Initialize chainEnd to negative infinity and count = 0.
  3. Iterate through the sorted pairs. For each pair [a, b]:
    • If a > chainEnd, this pair can extend the chain. Increment count and set chainEnd = b.
  4. Return count.

Example Walkthrough

1Sorted by end value: [[1,2],[2,3],[3,4]]. chainEnd=-inf, count=0
0
1
0
1
i
2
i
1
2
3
2
3
4
1/5

Code