Exponential Search
Doubles a bound to find a range, then binary searches it; very fast for values near the start.
Worth knowing first
#How does it work?
Exponential search first finds a range that must contain the target in a sorted array, then binary searches that range.
To find the range, a bound doubles 1, 2, 4, 8, … until the value at the bound passes the target. The target must lie between the last two bounds.
It is very fast when the target is near the start, and it works without knowing the array's length (unbounded or streaming data).
#Live animation
The array is sorted. Target: 24. First we find a range by doubling a bound, then binary search it.
if a[0] == target: return 0bound = 1while bound < n and a[bound] < target: bound = bound · 2lo = bound / 2; hi = min(bound, n - 1)binary search in a[lo..hi]return -1
#Step by step
- 01Check the first element; if it is the target, done.
- 02Start the bound at 1.
- 03Double the bound while a[bound] is smaller than the target.
- 04The target must be in [bound/2, bound].
- 05Binary search that range.
#Example code
The same algorithm in 8 languages. Every program is compiled, run and checked to print the same output.
def binary_search(a: list[int], lo: int, hi: int, target: int) -> int:
while lo <= hi:
mid = (lo + hi) // 2
if a[mid] == target:
return mid
if a[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1
def exponential_search(a: list[int], target: int) -> int:
"""a must be sorted. Doubles a bound until it passes the target, then binary searches behind it."""
if not a:
return -1
if a[0] == target:
return 0
bound = 1
while bound < len(a) and a[bound] < target:
bound *= 2
return binary_search(a, bound // 2, min(bound, len(a) - 1), target)
numbers = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
print(exponential_search(numbers, 13))
print(exponential_search(numbers, 4))#Complexity
| Best | O(1) |
|---|---|
| Average | O(log i) |
| Worst | O(log n) |
| Extra memory | O(1) |
| Needs sorted data? | Yes |
i is the position of the target. Finding the bound takes log i steps, and the binary search within the range takes log i more. So a target near the start is found quickly however large n is. The worst case is O(log n), the same as binary search.
#When to use it?
Used on sorted data of unknown or huge size (unbounded lists, paged results) and when targets tend to be near the start. Also known as galloping search; Timsort uses it while merging runs.
#Practice
Log in to answer questions and save your progress.
Easy
How does exponential search find its range?
- 1By doubling a bound: 1, 2, 4, 8…
- 2By halving the array
- 3By visiting elements one by one
- 4By picking random positions
Which search runs once the range is found?
- 1Binary search
- 2Linear search
- 3Jump search
- 4Hash lookup
If the target is at position i, what is exponential search's complexity?
- 1O(log i)
- 2O(i)
- 3O(√i)
- 4O(log n)
Medium
In a 64-element array with the target at index 20, at which bound does the doubling stop?
- 132
- 216
- 364
- 420
Hard
When is exponential search especially better than binary search?
- 1When the size is unknown or targets are near the start
- 2When the data isn't sorted
- 3When the array is tiny
- 4When values repeat