Find the smallest element in a sorted array that has been rotated around an unknown pivot.
Rotated array minimum search finds the smallest element in a sorted array that has been rotated around an unknown pivot.
For example:
may become:
The minimum element is the rotation point.
Problem
Given a rotated sorted array of length , find an index such that
Assume first that all values are distinct.
Key Idea
Compare the middle element with the right boundary.
If
then the minimum lies strictly to the right of .
If
then the minimum lies at or to the left of .
This works because the right side tells us whether the midpoint is in the upper rotated part or the lower sorted part.
Algorithm
rotated_array_minimum_search(A):
l = 0
r = length(A) - 1
while l < r:
m = l + (r - l) // 2
if A[m] > A[r]:
l = m + 1
else:
r = m
return lExample
Let
Steps:
| step | l | r | m | A[m] | A[r] | action |
|---|---|---|---|---|---|---|
| 1 | 0 | 5 | 2 | 11 | 5 | move right |
| 2 | 3 | 5 | 4 | 3 | 5 | move left |
| 3 | 3 | 4 | 3 | 1 | 3 | move left |
Return index .
The minimum value is:
Correctness
The algorithm maintains the invariant:
- The minimum element lies in the current interval .
If , then lies in the upper part before the rotation point. Since is smaller than , the minimum cannot be at or to its left, so the algorithm moves to .
If , then lies in the lower sorted part, or the interval is already normally sorted. The minimum may be at or to the left, so the algorithm moves to .
The interval shrinks each iteration. When , only the minimum index remains.
Complexity
| case | time |
|---|---|
| distinct values |
Space:
Handling Duplicates
With duplicates, the comparison
can be ambiguous. A safe fallback is to shrink the right boundary:
if A[m] == A[r]:
r = r - 1This preserves correctness but may degrade worst-case time to:
Use Cases
- Find rotation pivot
- Recover sorted order from rotated data
- Search in rotated arrays
- Detect smallest timestamp or key after cyclic shift
Implementation
def rotated_array_minimum_search(a):
if not a:
return -1
l, r = 0, len(a) - 1
while l < r:
m = l + (r - l) // 2
if a[m] > a[r]:
l = m + 1
else:
r = m
return lfunc RotatedArrayMinimumSearch(a []int) int {
if len(a) == 0 {
return -1
}
l, r := 0, len(a)-1
for l < r {
m := l + (r-l)/2
if a[m] > a[r] {
l = m + 1
} else {
r = m
}
}
return l
}