Find the Longest Valid Obstacle Course at Each Position - Complete Solution Guide
Find the Longest Valid Obstacle Course at Each Position is LeetCode problem 1964, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
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 th 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 i th obstacle in the course. You must put the chosen obstacles in the same order as they appear in obstacles . Every obstacle
Detailed Explanation
The problem asks us to find, for each position `i` in an array `obstacles`, the length of the longest obstacle course ending at that position, subject to the following constraints: the course must include the obstacle at index `i`, obstacles must be chosen in their original order, and the height of each obstacle (except the first) must be greater than or equal to the height of the previous one. In simpler terms, we are looking for the length of the Longest Non-decreasing Subsequence (LNDS) ending at each index `i`, where the element at index `i` is definitely included in the LNDS.
Solution Approach
The provided solution uses a dynamic programming approach combined with binary search. It iterates through the `obstacles` array, maintaining a list `lis` that represents the smallest tail elements of all possible non-decreasing subsequences encountered so far. For each obstacle at index `i`, the solution uses binary search (`bisect_right` in Python, `binarySearchRight` in Java, `upper_bound` in C++, `bisect_right` in C) to find the position where the current obstacle can either extend an existing subsequence or replace a larger tail element to form a smaller tail element for a subsequence of the same length. The index returned by the binary search plus one gives the length of the longest obstacle course ending at index `i`.
Step-by-Step Algorithm
- Step 1: Initialize an empty list `lis` to store the smallest tail elements of non-decreasing subsequences.
- Step 2: Initialize an empty list `ans` to store the length of the longest obstacle course at each position.
- Step 3: Iterate through the `obstacles` array from left to right.
- Step 4: For each obstacle, use binary search to find the index where it can be inserted into the `lis` list while maintaining the non-decreasing property and smallest tail elements.
- Step 5: If the binary search returns an index equal to the length of `lis`, it means the current obstacle is larger than all existing tail elements and extends the longest subsequence found so far. Append it to `lis`.
- Step 6: If the binary search returns an index within the bounds of `lis`, it means the current obstacle can replace a larger tail element to form a non-decreasing subsequence of the same length but with a smaller tail element. Replace the element at that index with the current obstacle.
- Step 7: Append the index returned by the binary search plus one to the `ans` list, representing the length of the longest obstacle course ending at the current position.
- Step 8: After iterating through all obstacles, return the `ans` list.
Key Insights
- Insight 1: The problem is essentially about finding the length of the Longest Non-decreasing Subsequence (LNDS) ending at each index, with a constraint to include the obstacle at that index.
- Insight 2: We can use binary search to efficiently maintain and update the LNDS. Instead of storing the entire LNDS sequence, we only need to store the smallest tail element for each possible subsequence length.
- Insight 3: The `lis` list maintains the increasing order of obstacle heights and can be updated efficiently using binary search to find the correct position to insert or replace elements.
Complexity Analysis
Time Complexity: O(n log n)
Space Complexity: O(n)
Topics
This problem involves: Array, Binary Search, Binary Indexed Tree.
Companies
Asked at: Morgan Stanley.