Upper bound finds the first index at which elements become strictly greater than a value . It returns the smallest index such that
If no such index exists, it returns .
This operation complements lower bound and allows precise range queries over equal values.
Problem
Given a sorted array of length and a value , find the smallest index such that
Return if all elements are .
Key Idea
The predicate
is monotone:
- false for smaller indices
- true for larger indices
Binary search isolates the first true position.
Algorithm
Use a half-open interval .
upper_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 right |
| 2 | 3 | 5 | 4 | 7 | move left |
| 3 | 3 | 4 | 3 | 5 | move left |
Return index .
Interpretation
- All indices satisfy
- All indices satisfy
This splits the array into two regions.
Relation to Lower Bound
| operation | condition | meaning |
|---|---|---|
| lower bound | first occurrence of or insertion point | |
| upper bound | position after last occurrence of |
Range of equal elements:
Correctness
Invariant:
- The answer remains in
Each step eliminates half the interval while preserving:
- left side contains only false values
- right side contains possible true values
Termination at yields the first true index.
Complexity
| case | time |
|---|---|
| all cases |
Space:
Use Cases
- Count elements
- Find right boundary of duplicates
- Range counting and interval queries
- Partitioning sorted data
Implementation
def upper_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 UpperBound(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
}