Problem Description
Given an integer array nums, find the length of the longest contiguous (non‐empty) subarray such that the first element is strictly greater than the last element (i.e. the subarray is “semi-decreasing”). If no such subarray exists, return 0.
Key Insights
- Only the two endpoints matter; the interior values do not affect whether the subarray is semi-decreasing.
- For any subarray defined by indices i and j (with i < j), the condition reduces to nums[i] > nums[j].
- Maximizing the subarray length is equivalent to finding a pair (i, j) with i < j, nums[i] > nums[j] and j-i+1 as large as possible.
- A monotonic stack can be used to record candidate left endpoints. In our solution we maintain only those indices that are “optimal” – they appear in increasing order with respect to index and (consequently) increasing order in value when we only push a new index if its value is strictly greater than the last candidate’s value.
- Then for each candidate right endpoint (scanning from the end toward the beginning), we use binary search on the candidate list (restricted to indices less than j) to quickly find the left endpoint with the smallest index that still satisfies nums[i] > nums[j].
Space and Time Complexity
Time Complexity: O(n log n) – building the candidate list takes O(n) and for each of the n indices we potentially perform a binary search (log n). Space Complexity: O(n) – for storing the candidate indices and their corresponding values.
Solution
We first build a candidate “stack” of left indices. The idea is: while iterating from left to right, we add index i only if nums[i] is strictly greater than the value at the last candidate index (or if the candidate list is empty). This is because a candidate with a lower index and a higher value is strictly better when we try to maximize the subarray’s length.
After building the candidate list (which is sorted by index and also by increasing value thanks to our push condition), we iterate from the far right end of the array backward. For each index j (serving as a potential right endpoint), we need to choose a candidate left index that is less than j and has a value greater than nums[j]. Since the candidate values are sorted in ascending order, we can use binary search (on the portion of the candidate list that contains indices < j) to find the leftmost candidate that is greater than nums[j]. The answer is then updated with j - candidate_index + 1 if this width is larger than the current maximum.
A few important notes:
- If no such candidate is found for any j, the answer remains 0.
- Even though the subarray length is computed as j - i + 1, a valid subarray must have at least 2 elements.
- We take “strictly greater” into account in the binary search: even if nums[candidate] equals nums[j] the condition fails.