Skip to content

2096. Find The Longest Valid Obstacle Course At Each Position

Array Binary Search Binary Indexed Tree

Problem - Find The Longest Valid Obstacle Course At Each Position

Hard

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 and i 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 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 <= 105
  • 1 <= obstacles[i] <= 107

Solutions

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# class BinaryIndexedTree:
#     def  __init__ (self, n: int):
#         self.n = n
#         self.tree = [0] * (n + 1)

#     def update(self, index: int, val: int):
#         while index <= self.n:
#             self.tree[index] = max(self.tree[index], val)
#             index += index & -index

#     def query(self, index: int):
#         result = 0
#         while index:
#             result = max(self.tree[index], result)
#             index -= index & -index
#         return result

# class Solution:
#     def longestObstacleCourseAtEachPosition(self, obstacles: List[int]) -> List[int]:
#         nums = sorted(set(obstacles))
#         n = len(nums)

#         tree = BinaryIndexedTree(n)
#         result = []
#         for val in obstacles:
#             idx = bisect_left(nums, val) + 1
#             result.append(tree.query(idx) + 1)
#             tree.update(idx, result[-1])
#         return result

class Solution:
    def longestObstacleCourseAtEachPosition(self, obstacles: List[int]) -> List[int]:
        count = 0
        dp, result = [], []

        for ob in obstacles:
            if not dp or ob >= dp[-1]:
                dp.append(ob)
                count += 1
                result.append(count)
            else:
                idx = bisect_right(dp, ob)
                dp[idx] = ob
                result.append(idx + 1)
        return result

Submission Stats:

  • Runtime: 102 ms (100.00%)
  • Memory: 35.2 MB (58.71%)