function exponentialSearch(array: number[], target: number) {if (array[0] === target) return 0;
let bound = 1;
while (bound < array.length && array[bound] < target) bound *= 2;
let low = Math.floor(bound / 2), high = Math.min(bound, array.length - 1);
while (low <= high) {const middle = (low + high) >> 1;
if (array[middle] === target) return middle;
if (array[middle] < target) low = middle + 1;
else high = middle - 1;
}
return -1;
}
Look for 33. First check array[0] = 7, not it.
Understanding Exponential search
The idea
Exponential search first finds a range that must contain the target by probing indices 1, 2, 4, 8, … until the value there is at least the target. The target then lies between the last two bounds, a range of at most half the bound, and a binary search finishes the job.
The cost is 2 log i for a target at index i, not log n: a target near the front is found quickly whatever the array size, and the array does not even need a known size. That makes it the standard way to search unbounded or infinite sorted streams.
The four stages
Complexity
Versus its siblings
Pseudocode
EXPONENTIALSEARCH(array, target)
if array[0] = target: return 0
bound ← 1; while bound < n and array[bound] < target: bound ← 2 × bound
low ← bound / 2; high ← min(bound, n − 1)
binary search for target inside [low, high]
When to use
Pitfalls
History
Jon Bentley and Andrew Yao described it in 1976 as a search for unbounded sorted lists, also called galloping or doubling search. Peter McIlroy's 1993 merge and Tim Peters's Timsort use galloping to merge runs of very different lengths in near-linear time.