Interpolation Search
Looks where the value should be rather than in the middle; very fast on evenly spread data.
Worth knowing first
#How does it work?
Interpolation search narrows the range like binary search, but instead of the middle it looks where the value should be, like opening a phone book near the end when looking for "Wilson".
The position is estimated by proportion from the values at both ends of the range: if the target is x% of the way between them by value, we look about x% of the way along by position.
With evenly spread values it can find the target in a single probe. With very skewed data (say 1, 2, 3, 1000000) the guesses get poor and it can slow down to linear search.
#Live animation
The array is sorted. Target: 24. Instead of the middle, we look where the value should be.
lo = 0; hi = n - 1while lo <= hi and a[lo] <= target <= a[hi]:pos = lo + (target - a[lo]) · (hi - lo) / (a[hi] - a[lo])if a[pos] == target: return posif a[pos] < target: lo = pos + 1 else: hi = pos - 1return -1
#Step by step
- 01Take the whole array as the range with lo and hi.
- 02If the target isn't between a[lo] and a[hi], stop: it isn't there.
- 03Estimate the position: pos = lo + (target − a[lo]) · (hi − lo) / (a[hi] − a[lo]).
- 04If a[pos] is the target, done; if smaller set lo = pos + 1, if larger set hi = pos − 1.
- 05Repeat until the range is empty.
#Example code
The same algorithm in 8 languages. Every program is compiled, run and checked to print the same output.
def interpolation_search(a: list[int], target: int) -> int:
"""a must be sorted. Guesses the position from the values instead of taking the middle."""
lo, hi = 0, len(a) - 1
while lo <= hi and a[lo] <= target <= a[hi]:
if a[hi] == a[lo]:
pos = lo
else:
pos = lo + (target - a[lo]) * (hi - lo) // (a[hi] - a[lo])
if a[pos] == target:
return pos
if a[pos] < target:
lo = pos + 1
else:
hi = pos - 1
return -1
numbers = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
print(interpolation_search(numbers, 13))
print(interpolation_search(numbers, 4))#Complexity
| Best | O(1) |
|---|---|
| Average | O(log log n) |
| Worst | O(n) |
| Extra memory | O(1) |
| Needs sorted data? | Yes |
With uniformly distributed values the average is O(log log n) probes: 4–5 for a million elements. In the worst case (very skewed data) each probe removes just one element and time grows to O(n). There is no O(log n) guarantee as with binary search.
#When to use it?
Faster than binary search on large, sorted, roughly evenly spread data (sequential ids, timestamps, evenly spaced measurements). If the distribution is unknown or skewed, binary search is the safer choice.
#Practice
Log in to answer questions and save your progress.
Easy
How does interpolation search differ from binary search?
- 1It probes an estimated position instead of the middle
- 2It doesn't need sorted data
- 3It visits elements one by one
- 4It only works on linked lists
What is interpolation search's average complexity on uniformly distributed data?
- 1O(log log n)
- 2O(log n)
- 3O(√n)
- 4O(n)
What is interpolation search's worst case?
- 1O(n)
- 2O(log n)
- 3O(1)
- 4O(n log n)
Medium
Searching for 70 in [10, 20, 30, …, 100], what is the first estimated index?
- 16
- 25
- 34
- 47
Hard
On which array does interpolation search perform worst?
- 1[1, 2, 3, 4, 5, 1000000]
- 2[2, 4, 6, 8, 10, 12]
- 3[10, 20, 30, 40, 50, 60]
- 4[5, 15, 25, 35, 45, 55]