Last Updated: April 2, 2026
We have a collection of envelopes, each defined by a width and a height. Envelope A fits inside envelope B only when A's width is strictly less than B's width AND A's height is strictly less than B's height. We want to find the longest chain of envelopes where each one nests inside the next.
This is essentially a longest chain problem in two dimensions. If the envelopes only had one dimension, it would reduce to the classic Longest Increasing Subsequence (LIS). The twist is that we need both dimensions to be strictly increasing, and equal dimensions do not count.
The key observation that unlocks the optimal approach: if we can cleverly sort the envelopes to reduce the 2D problem to a 1D problem, we can apply LIS techniques directly on the heights.
1 <= envelopes.length <= 10^5 → With up to 100,000 envelopes, O(n^2) dynamic programming (10^10 operations) will time out. We need O(n log n) or better.1 <= wi, hi <= 10^5 → Widths and heights are positive integers, so we don't need to handle negatives or zeros.The most natural way to think about this problem is as a variant of Longest Increasing Subsequence in two dimensions. If we sort the envelopes by width (and break ties by height), then for each envelope we can look at all previous envelopes and check if the current one can contain them.
This is the same idea as the classic O(n^2) LIS: for each element, check all elements before it and extend the longest valid chain. The only difference is that our "increasing" condition requires both width and height to be strictly increasing.
dp array where dp[i] represents the length of the longest chain ending with envelope i.dp[i] = 1 (each envelope is a chain of length 1 by itself).i, look at all previous envelopes j (where j < i). If envelopes[j] fits inside envelopes[i] (both width and height are strictly less), then dp[i] = max(dp[i], dp[j] + 1).dp array.This approach works but is too slow for n = 10^5. What if we sorted the envelopes so that the width condition is automatically satisfied, reducing it to a 1D LIS problem on heights that we can solve in O(n log n)?
If we sort envelopes by width ascending, then any subsequence in sorted order has non-decreasing widths. But we need strictly increasing widths and heights. The trick: for equal widths, sort heights descending. This prevents two same-width envelopes from both appearing in the LIS on heights. After sorting, the problem becomes exactly LIS on the heights array, which we solve in O(n log n) using patience sorting (binary search with a tails array).
By sorting widths ascending, any left-to-right subsequence automatically has non-decreasing widths. The descending height sort for equal widths ensures that we never accidentally pick two envelopes with the same width in our LIS, because their heights are presented in decreasing order, and an increasing subsequence can't include two decreasing consecutive values. After sorting, the problem is exactly LIS on the heights array.
tails array where tails[i] is the smallest tail of any increasing subsequence of length i+1. For each height, binary search for the leftmost position where tails[pos] >= height. Replace or append accordingly.tails is the answer.