Tag
:
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
between0
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 theobstacle
immediately before it.
Return an array ans
of length n
, where ans[i]
is the length of the longest obstacle course for index i
as described above.
Example 1:
Input: obstacles = [1,2,3,2]
Output: [1,2,3,3]
Explanation: The longest valid obstacle course at each position is:
- i = 0: [1], [1] has length 1.
- i = 1: [1,2], [1,2] has length 2.
- i = 2: [1,2,3], [1,2,3] has length 3.
- i = 3: [1,2,3,2], [1,2,2] has length 3.
Example 2:
Input: obstacles = [2,2,1]
Output: [1,2,1]
Explanation: The longest valid obstacle course at each position is:
- i = 0: [2], [2] has length 1.
- i = 1: [2,2], [2,2] has length 2.
- i = 2: [2,2,1], [1] has length 1.
Example 3:
Input: obstacles = [3,1,5,6,4,2]
Output: [1,1,2,3,2,2]
Explanation: The longest valid obstacle course at each position is:
- i = 0: [3], [3] has length 1.
- i = 1: [3,1], [1] has length 1.
- i = 2: [3,1,5], [3,5] has length 2. [1,5] is also valid.
- i = 3: [3,1,5,6], [3,5,6] has length 3. [1,5,6] is also valid.
- i = 4: [3,1,5,6,4], [3,4] has length 2. [1,4] is also valid.
- i = 5: [3,1,5,6,4,2], [1,2] has length 2.
Constraints:
n == obstacles.length
1 <= n <= 10^5
1 <= obstacles[i] <= 10^7
Overview
As shown in the picture, we have 4
obstacles.
- The longest course ending at
obstacles[0]
contains1
obstacle,obstacles[0]
itself. - The longest course ending at
obstacles[1]
contains2
obstacles,obstacles[0]
and[1]
. - The longest course ending at
obstacles[2]
contains3
obstacles,obstacles[0]
,[1]
, and[2]
. - The longest course ending at
obstacles[3]
contains3
obstacles,obstacles[0]
,[1]
, and[3]
. Note that the course must be non-decreasing so it can't containobstacles[2]
as it is taller thanobstacles[3]
.
We need to find answer
, where answer[i]
represents the length of the longest course that ends with obstacles[i]
. In our case, answer = [1, 2, 3, 3]
.
Algorithm
- Initialize an empty array
lis
, an arrayanswer
of the same length asobstacles
. - Iterate over
obstacles
. At each stepi
, we findidx
, the rightmost insertion position ofobstacles[i]
tolis
.
- If
idx
equals the length oflis
, appendobstacles[i]
tolis
. - Otherwise, update
lis[idx] = obstacles[i]
. - Update
answer[i] = idx + 1
.
- Return
answer
once the iteration ends.
class Solution:
def longestObstacleCourseAtEachPosition(self, obstacles: List[int]) -> List[int]:
n = len(obstacles)
answer = [1] * n
lis = list()
for i, height in enumerate(obstacles):
lo, hi = 0, len(lis)
while lo < hi:
mi = lo + (hi - lo) // 2
if lis[mi] <= height:
lo = mi + 1
else:
hi = mi
idx = lo
if idx == len(lis):
lis.append(height)
else:
lis[idx] = height
answer[i] = idx + 1
return answer
class Solution:
def longestObstacleCourseAtEachPosition(self, obstacles: List[int]) -> List[int]:
n = len(obstacles)
answer = [1] * n
lis = list()
for i, height in enumerate(obstacles):
idx = bisect.bisect_right(lis, height)
if idx == len(lis):
lis.append(height)
else:
lis[idx] = height
answer[i] = idx + 1
return answer