Find the Longest Valid Obstacle Course at Each Position
Leetcode Daily Challenge (7th May, 2023)
Problem Statement:-
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 i<sup>th</sup>
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
i<sup>th</sup>
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.
Link: https://leetcode.com/problems/find-the-longest-valid-obstacle-course-at-each-position/description/
Problem Explanation with examples:-
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<sup>5</sup>
1 <= obstacles[i] <= 10<sup>7</sup>
Intuition:-
We need to find the longest increasing subsequence in the array (obstacles) till the current index for each index.
We can use binary search to find the index of the first element in the dp array which is greater than the current element and the very next index will be the length of the longest increasing subsequence till the current index.
Solution:-
Create a dp array of size n+1 and initialize it with 10^8, also create a res array.
Iterate over the obstacles array and for each element find the index of the first element in the dp array which is greater than the current element using binary search.
Append the index+1 to the res array and update the dp array at index idx with the current element.
Return the res array.
Code:-
JAVA Solution
class Solution {
public int[] longestObstacleCourseAtEachPosition(int[] obstacles) {
List<Integer> res = new ArrayList<>();
int[] dp = new int[obstacles.length+1];
Arrays.fill(dp, Integer.MAX_VALUE);
for (int i = 0; i < obstacles.length; i++) {
int idx = Arrays.binarySearch(dp, obstacles[i]);
if (idx < 0) {
idx = -(idx+1);
}
res.add(idx+1);
dp[idx] = obstacles[i];
}
int[] result = new int[res.size()];
for (int i = 0; i < res.size(); i++) {
result[i] = res.get(i);
}
return result;
}
}
Python Solution
class Solution:
def longestObstacleCourseAtEachPosition(self, obstacles: List[int]) -> List[int]:
res = []
dp = [10**8]*(len(obstacles)+1)
for i in obstacles:
idx = bisect.bisect(dp,i)
res.append(idx+1)
dp[idx] = i
return res
Complexity Analysis:-
TIME:-
The time complexity is O(nlogn) , where n is the length of the input array obstacles
. This is because the algorithm uses binary search to find the index to insert each element, and binary search has a time complexity of O(log n).
SPACE:-
The space complexity is O(n), where n is the length of the input array obstacles
. This is because we use an array of length obstacles.length+1
to store the increasing subsequence of obstacles. Additionally, we use an ArrayList
to store the result, which has a worst-case space complexity of O(n).