Given a bitonic array and element x in the array, find the index of x in 2logn time
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A bitonic array increases up to one peak and then decreases. That shape lets you search faster than a linear scan because both halves are ordered, just in opposite directions.
The Main Idea
To find the index of a value x in O(log n) time, split the problem into two binary searches:
- find the peak element in
O(log n) - binary-search the increasing half
- binary-search the decreasing half
People often describe this as 2 log n, but asymptotically it is still O(log n) because the constant factor does not change the class.
The key observation is that once you know the peak index, the array becomes two sorted ranges:
- left side: strictly increasing
- right side: strictly decreasing
Binary search works on both as long as you compare in the correct direction.
Finding the Peak
The peak is the index where the array stops rising and starts falling. Because the slope tells you which side to move toward, you can find it with a modified binary search.
If arr[mid] is smaller than the next element, you are still on the rising side, so the peak must be to the right. Otherwise you are at the peak or on the falling side, so move left.
Binary Search on Each Side
After locating the peak, search the left side with ordinary ascending-order binary search. If that fails, search the right side with a descending-order variant.
Notice the reversed comparisons in the descending search. That is the part people most often get wrong.
Full Solution
Now combine the three steps into one function.
This solution uses constant extra space and performs a logarithmic number of comparisons.
Why the Complexity Works
The peak search is O(log n). The ascending search is another O(log n), and the descending search is also O(log n). In the worst case you do all three, which is still O(log n).
If you want to be explicit about the arithmetic, the work looks like:
- one peak search
- up to one ascending search
- up to one descending search
That is roughly 3 log n comparisons, which is still logarithmic time.
Edge Cases to Think About
A good implementation should also consider:
- a single-element array
- a peak at the first or last position
- a target equal to the peak
- values not present in the array
If the array is not strictly bitonic, meaning duplicates appear around the top, the logic may need extra handling. The cleanest version of this problem assumes strictly increasing values before the peak and strictly decreasing values after it.
Common Pitfalls
Using ordinary binary search on the decreasing half without reversing the comparison logic returns wrong answers even though the code looks almost correct.
Accessing arr[mid + 1] without maintaining the low < high loop condition can produce an index error near the end of the array.
Forgetting to check whether the peak itself matches the target adds unnecessary work and can hide simple bugs.
Assuming the input is bitonic when it is not can make the algorithm return incorrect results. Validate the problem constraints if the data source is unreliable.
Summary
- Search a bitonic array by first finding the peak with modified binary search.
- Then run binary search on the increasing half and, if needed, on the decreasing half.
- The total time remains
O(log n). - The descending-half search must reverse the usual binary-search comparisons.
- The approach is efficient and uses only
O(1)extra space.

