Lower bound finds the first index at which a value can be inserted in a sorted array while preserving order. It returns the smallest index such that
If all elements are smaller than , it returns .
This operation forms the basis of many ordered data structure queries, including range queries and duplicate handling.
Problem
Given a sorted array of length and a value , find the smallest index such that
Return if no such index exists.
Key Idea
The predicate
is monotone:
- false for small indices
- true for large indices
Binary search can locate the first true position.
Algorithm
Maintain a half-open interval .
lower_bound(A, x):
l = 0
r = length(A)
while l < r:
m = l + (r - l) // 2
if A[m] < x:
l = m + 1
else:
r = m
return lExample
Let
and
Steps:
| step | l | r | m | A[m] | action |
|---|---|---|---|---|---|
| 1 | 0 | 5 | 2 | 3 | move left |
| 2 | 0 | 2 | 1 | 3 | move left |
| 3 | 0 | 1 | 0 | 1 | move right |
Return index .
Interpretation
- All indices satisfy
- All indices satisfy
This partitions the array.
Correctness
Invariant:
- The answer always lies in
Each step reduces the interval while preserving:
- left side contains only false values
- right side contains only possible true values
When , the first true index has been isolated.
Complexity
| case | time |
|---|---|
| all cases |
Space:
Use Cases
- Insert position in sorted array
- Count elements less than
- Range queries: combine with upper bound
- Deduplication boundaries
Implementation
def lower_bound(a, x):
l, r = 0, len(a)
while l < r:
m = l + (r - l) // 2
if a[m] < x:
l = m + 1
else:
r = m
return lfunc LowerBound(a []int, x int) int {
l, r := 0, len(a)
for l < r {
m := l + (r-l)/2
if a[m] < x {
l = m + 1
} else {
r = m
}
}
return l
}