Problem
You want to build some obstacle courses. You are given a 0-indexed integer array obstacles
of length n
, where obstacles[i]
describes the height of the ith
obstacle.
For every index i
between 0
and n - 1
(inclusive), find the length of the longest obstacle course in obstacles
such that:
- You choose any number of obstacles between
0
andi
inclusive. - You must include the
ith
obstacle in the course. - You must put the chosen obstacles in the same order as they appear in
obstacles
. - Every obstacle (except the first) is taller than or the same height as the obstacle immediately before it.
Return an array ans
of length n
, where ans[i]
is the length of thelongest obstacle course for index i
as described above.
Examples
Example 1
|
|
Example 2
|
|
Example 3
|
|
Constraints
n == obstacles.length
1 <= n <= 10^5
1 <= obstacles[i] <= 10^7
Solution
Method 1 – Patience Sorting (Binary Search)
Intuition
We want, for each position, the length of the longest non-decreasing subsequence ending at that position. This is similar to the Longest Increasing Subsequence (LIS) problem, but allows equal values. We can use a variant of patience sorting with binary search to efficiently compute the answer.
Approach
- Initialize an empty list
seq
to keep track of the smallest possible ending values for subsequences of each length. - For each obstacle at index
i
:- Use binary search (
bisect_right
in Python) to find the rightmost position inseq
whereobstacles[i]
can be placed (since equal values are allowed). - If the position is equal to the length of
seq
, append the obstacle; otherwise, replace the value at that position. - The answer for this position is the index + 1.
- Use binary search (
- Return the answer array.
Code
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n log n)
, since each position uses binary search. - 🧺 Space complexity:
O(n)
, for the sequence and answer arrays.