Search in Rotated Sorted Array
Search in Rotated Sorted Array
An array sorted in ascending order is rotated at an unknown pivot. Given the array and a target, return the index of the target or -1 if not found. All values are distinct.
Why this is worth learning
Rotation leaves at least one half around the midpoint sorted when values are distinct. Determine which half is ordered before deciding whether the target belongs inside its value range.
Before coding: one-minute experiment
In [4,5,6,7,0,1,2], with midpoint value 7 and target 1, why can the sorted left half be discarded?
Function signature
func Search(nums []int, target int) int
Inputs / outputs
nums: rotated sorted array with distinct values.target: value to search.- Return: index of target, or -1.
Example
nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Constraints
- 1 <= len(nums) <= 100_000
Core idea (near-solution)
A scan ignores the useful order that survived rotation. With distinct values, the midpoint splits the candidate interval so at least one half is sorted. Recognize that half first, then use its endpoint values to decide whether target can lie there. Comparing target with the midpoint alone is insufficient because the other half may cross the wrap from largest to smallest.
Binary search by identifying which half is sorted. The target must lie in one of the halves.
Invariant: the target (if it exists) is always within the current [lo, hi] range.
Algorithm (step-by-step)
- Set
lo = 0,hi = len(nums)-1. - While
lo <= hi:mid = lo + (hi-lo)/2.- If
nums[mid] == target, returnmid. - If left half is sorted (
nums[lo] <= nums[mid]):- If
nums[lo] <= target < nums[mid], move left (hi = mid-1), else move right.
- If
- Else right half is sorted:
- If
nums[mid] < target <= nums[hi], move right (lo = mid+1), else move left.
- If
- Return -1.
Correctness sketch
The inclusive interval contains the target if it exists. After checking midpoint equality, compare nums[lo] with nums[mid]. If the left half is sorted, its closed-open value range [nums[lo],nums[mid]) contains target exactly when the remaining left half could contain it; otherwise discard that half. If the left half crosses the rotation point, the right half is sorted, and the analogous range (nums[mid],nums[hi]] decides whether to keep it. Distinct values make this classification unambiguous. Every update excludes the checked midpoint and strictly reduces the interval without discarding a possible target.
Trace (hand walkthrough)
Example input:
nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Walk:
- lo=0 hi=6 mid=3 val=7; left sorted [4..7], target 0 not in -> lo=4
- lo=4 hi=6 mid=5 val=1; left sorted [0..1], target 0 in -> hi=4
- mid=4 val=0 -> found index 4
Pitfalls to avoid
- Misplacing the boundary comparisons (
<=vs<). - Forgetting the distinct-values assumption; this logic relies on it.
Debugging lens
Test every pivot, an unrotated input, absent targets between values, and both endpoints. The use of <= when recognizing the sorted left half matters for a one-element half.
Complexity
- Time:
O(log n). - Extra space:
O(1).
Implementation notes (Go)
- Use
lo + (hi-lo)/2to avoid overflow.
Reconstruction checkpoint
In [4,5,6,7,0,1,2], with midpoint value 7 and target 1, why can the sorted left half be discarded?
Model answer
The left half covers values 4 through 7, and target 1 is outside that ordered range. The target, if present, must be in the right half crossing down through the rotation.