Find the first element strictly less than a key in a vector sorted in descending order
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When a vector is sorted in descending order, ordinary binary-search intuition needs to be flipped. To find the first element strictly less than a key, you want the leftmost position where the descending sequence drops below that key.
This is a good fit for binary search because the predicate changes only once. Elements before the answer are greater than or equal to the key, and elements from the answer onward are strictly less than the key.
The Search Condition
Suppose the vector is:
[9, 7, 7, 5, 3, 1]
and the key is 6. The answer is index 3, which holds 5. Everything before index 3 is greater than or equal to 6, and everything from index 3 onward is less than 6.
That monotonic split is exactly what binary search needs.
A Direct Binary Search Solution
Here is a C++ implementation that returns the index of the first element strictly less than key, or -1 if no such element exists:
The logic is easy to miss at first because the data is descending. If v[mid] < key, then mid is a valid answer, but there may be an earlier valid index, so search left. Otherwise, the answer must be to the right.
Why This Works
The invariant is:
- indices before the answer contain values
>= key, - the answer and everything after it contain values
< key.
Binary search keeps shrinking the range until it isolates the first place where that transition happens.
This gives:
- time complexity
O(log n), - space complexity
O(1).
That is much better than a linear scan when the vector is large and you need to answer many queries.
Using std::lower_bound with a Comparator
You can also solve the problem with the standard library, but you need to be careful because the data is descending.
For many developers, the handwritten binary search is clearer because the intent is explicit. The standard-library version is compact, but it is easier to misuse when the ordering is reversed.
Edge Cases to Handle
There are a few cases worth testing explicitly:
- empty vector,
- key smaller than every element,
- key larger than every element,
- duplicates around the boundary.
For example, with [9, 7, 7, 5] and key 7, the correct answer is the first 5, not one of the 7 entries, because the requirement is strictly less than the key.
Common Pitfalls
- Reusing an ascending-order binary search without reversing the comparison logic.
- Returning the first element less than the key that you happen to find, rather than the leftmost one.
- Mixing up strictly less than with less than or equal to when duplicates exist.
- Forgetting to return
-1when no valid element exists. - Using the wrong standard-library function with a descending comparator and then trusting the result blindly.
Summary
- The problem is a binary-search boundary search on a descending vector.
- The correct answer is the leftmost index where
v[i] < key. - A direct binary search solves it in
O(log n)time andO(1)space. - Duplicates matter because the comparison is strictly less than, not less than or equal to.
- Standard-library algorithms can work too, but explicit binary search is often easier to reason about here.

