Search in Rotated Sorted Array

At every step, one half is still sorted — decide which, then whether the target lies in it.

Approach

Binary search as usual, but first determine which side of mid is sorted (compare nums[lo] to nums[mid]). If the target falls within that sorted side's range, search there; otherwise search the other half. The rotation never breaks the halving.

Time complexity

O(log n)

Space complexity

O(1)

Common mistake

Assuming the whole array is monotonic — you must check which half is sorted before choosing a direction.

Interactive walkthrough — step through it below, free and without an account

Problem

Given a strictly increasing array that was rotated around one unknown pivot, return the index of a target value. Return -1 when the target does not appear. Design the search to remain logarithmic despite the rotation.

Examples

Input: nums = [4,5,6,7,0,1,2], target = 0

Output: 4

The target 0 is at index 4. The left side of the first midpoint is sorted, but 0 is outside its range, so the search moves right.

Input: nums = [6,7,1,2,3,4,5], target = 8

Output: -1

The target is absent; each step discards the half that cannot contain 8.

Problem

Problem

Given a strictly increasing array that was rotated around one unknown pivot, return the index of a target value. Return `-1` when the target does not appear. Design the search to remain logarithmic despite the rotation.

Problem and Goal

Learning goal: Recognize why a rotated sorted array still supports logarithmic search.

Core idea A rotation moves a sorted prefix behind a sorted suffix, so the entire array may no longer be monotonic. However, for any chosen midpoint, at least one side of the midpoint is guaranteed to remain sorted. That local structure is enough to discard half of the remaining search interval.

Definition

The active search interval is the inclusive range from lo to hi. Every discarded index must be proven unable to contain the target.

Algorithm plan

  • Set lo = 0 and hi = n - 1.
  • Compute mid while lo <= hi.
  • Identify the sorted half using nums[lo] <= nums[mid].
  • Check whether the target lies within that half's endpoint range.
  • Keep that half when it can contain the target; otherwise keep the opposite half.

Micro-example For [4,5,6,7,0,1,2], midpoint value 7 makes [4,5,6,7] visibly sorted. Since 0 is not between 4 and 7, the answer must be to the right.

Pitfalls

  • Do not assume the whole array is monotonic.
  • Use inclusive comparisons at the sorted half's endpoints.
  • Use lo <= hi so a one-element interval is checked.

Recap

  • Rotation breaks global order, not every local half.
  • The sorted half tells us which direction is safe.
  • Each decision removes at least half the interval.

Problem and Goal

Search locally, not globally

The full array is not monotonic, but one half around `mid` is always sorted.

Identify the sorted half before choosing a direction.

Key Idea: Find the Sorted Half

Learning goal: Determine which half is sorted and use its value range to guide the search.

Core idea Compare nums[lo] with nums[mid]. If nums[lo] <= nums[mid], the left half is sorted; otherwise, the right half must be sorted. Once that half is known, its endpoints describe an ordinary sorted interval, so a target-range test tells us whether to search inside it.

Key insight

The rotation never breaks the halving property: one half is ordered, and the other half can be discarded when the target cannot fit in the ordered range.

Decision table

Sorted sideTarget belongs whenKeep
Left [lo..mid]nums[lo] <= target < nums[mid]Left: hi = mid - 1
Left [lo..mid]OtherwiseRight: lo = mid + 1
Right [mid..hi]nums[mid] < target <= nums[hi]Right: lo = mid + 1
Right [mid..hi]OtherwiseLeft: hi = mid - 1

Micro-example At lo = 0, mid = 3, hi = 6, values are 4, 7, 2. The left side is sorted, but target 0 is not in [4,7), so discard it.

Pitfalls

  • The sorted-side test comes before the target-range test.
  • The inequalities differ slightly because mid is already inspected.
  • “Target is smaller” alone is not enough to choose left after rotation.

Recap

  • nums[lo] <= nums[mid] identifies a sorted left half.
  • Range membership decides whether that half can contain the target.
  • The other case is symmetric for the right half.

Key Idea: Find the Sorted Half

Compare `nums[lo]` and `nums[mid]` to identify the sorted side.

`4 <= 7`, so indices `0..3` are sorted.

Main Approach and Correctness

Learning goal: Translate the sorted-half idea into a constant-space binary-search algorithm.

Core idea The loop maintains a simple invariant: if the target exists, it is inside the inclusive interval [lo, hi]. At each midpoint, either the left or right half is sorted. If the target lies inside that sorted half's value range, discard the opposite half; otherwise discard the sorted half. Because mid is checked first, the remaining interval always shrinks.

Algorithm plan

Code
lo = 0, hi = n - 1
while lo <= hi:
    mid = lo + (hi - lo) // 2
    if nums[mid] == target: return mid
    if nums[lo] <= nums[mid]:
        if nums[lo] <= target < nums[mid]: hi = mid - 1
        else: lo = mid + 1
    else:
        if nums[mid] < target <= nums[hi]: lo = mid + 1
        else: hi = mid - 1
return -1

Why it works

The sorted half has no hidden ordering break, so its endpoint comparison completely determines whether the target can be inside it.

Micro-example For target 0, the first midpoint is index 3 with value 7. The left half is sorted, but 0 is outside its range, so lo jumps to 4; the interval is cut from seven positions to three.

Pitfalls

  • Check equality at mid before changing boundaries.
  • Use mid + 1 and mid - 1 to avoid repeating a midpoint.
  • With distinct values, nums[lo] <= nums[mid] cleanly identifies the left-sorted case.

Recap

  • Maintain target containment in [lo, hi].
  • Identify order first, then test range membership.
  • Every iteration halves the candidates, giving O(log n) time.

Main Approach and Correctness

ApproachDecisionResult
Assume whole array is sortedCompare target with `nums[mid]` onlyUnsafe after rotation
Inspect one sorted halfCheck order, then target rangeCorrect `O(log n)` search

Walkthrough: Search for 0

Learning goal: Trace every boundary update on one complete example.

Core idea We will search nums = [4,5,6,7,0,1,2] for target = 0. The important question is not simply whether the target is smaller than nums[mid]; it is whether the target fits the sorted half identified at that step.

Trace

SteplomidhiSorted halfDecision
1036Left [4..7]0 is outside; move lo
2456Left [0..1]0 fits; move hi
3444Single elementnums[4] = 0; found

Micro-example After step 1, the surviving interval is [0,1,2] at indices 4..6. At step 2, the sorted left half has values [0,1], so target 0 must be there; checking index 4 finishes the search.

Boundary updates
  1. Check mid for equality.
  2. If the left half is sorted, test nums[lo] <= target < nums[mid].
  3. Otherwise test nums[mid] < target <= nums[hi].
  4. Move exactly one boundary beyond mid.

Pitfalls

  • Do not move hi merely because target is less than nums[mid].
  • Record the sorted half using the current boundaries, not the original array ends.
  • A one-element interval still requires an equality check.

Recap

  • The example takes three midpoint checks.
  • The rotation changes which half is sorted, not the halving process.
  • The final answer is index 4.

Walkthrough: Search for 0

End-to-end trace for nums = [4,5,6,7,0,1,2], target = 0.

Binary search
1 / 8
Start with the full array; inspect midpoint index 3.

Array

4567mid012
lo=0hi=6mid=3target=0check: mid=7 > target

Action: initialize

The left half is sorted because nums[lo] <= nums[mid].If 0 exists, it is inside indices 0 through 6.
1 / 8

Pitfalls and Edge Cases

Learning goal: Avoid the boundary mistakes that make rotated binary search incorrect.

Core idea The most common error is treating the rotated array as if its global order were intact. A comparison such as target < nums[mid] does not by itself reveal which boundary to move, because the pivot may lie between mid and the target. First classify the sorted half, then use that half's range.

Edge-case checklist

  • No rotation: The left half is sorted at every step, so the algorithm behaves like ordinary binary search.
  • Rotation at an endpoint: The array may look fully sorted; the same logic still works.
  • Target at lo or hi: Inclusive endpoint checks must preserve those candidates.
  • One element: The loop checks lo == hi before terminating.
  • Absent target: Boundaries cross only after every viable interval has been eliminated.

Common pitfall

Assuming the whole array is monotonic can send the search in the wrong direction. You must check which half is sorted before choosing a direction.

Micro-example At [4,5,6,7,0,1,2] with midpoint 7, target 0 is smaller than 7. That fact alone is misleading: the correct move is right, because the sorted left range is [4,7] and cannot contain 0.

Pitfalls

  • Forgetting < versus <= at the correct endpoint.
  • Leaving mid inside the interval after rejecting it.
  • Confusing “sorted half” with “half containing the target.”

Recap

  • Global monotonicity is false after rotation.
  • Local sortedness is sufficient.
  • Boundary updates must make strict progress.

Pitfalls and Edge Cases

At `mid = 3`, `nums[mid] = 7`, which move is correct for target `0`?

Complexity and Wrap-up

Learning goal: Justify the efficiency of the algorithm and retain its reusable pattern.

Core idea Each iteration performs a constant number of comparisons and discards one half of the active interval. The rotation changes the classification work, but it never changes the amount removed. The algorithm stores only three indices, so its auxiliary space remains constant.

Complexity

ResourceCostReason
TimeO(log n)The candidate interval is halved each iteration.
Extra spaceO(1)Only lo, hi, and mid are maintained.

Reusable pattern

Code
while the interval is nonempty:
    inspect midpoint
    identify a sorted half
    test target membership in that half
    discard the impossible half

Final invariant

If the target exists, it is always inside [lo, hi]; every boundary update preserves that claim.

Micro-example Seven candidates become three, then one, then a result. No auxiliary array is created, and no linear scan is needed.

Pitfalls

  • Calling the solution O(n) because the array is rotated.
  • Using extra storage to “unrotate” the array, which is unnecessary.
  • Forgetting that the binary-search proof depends on distinct values here.

Recap

  • Time: O(log n).
  • Space: O(1).
  • Rotation does not defeat binary search when one sorted half is identified first.

Complexity and Wrap-up

Summarize the costs of rotated-array binary search.

Complexity analysis
Time
O(log n)
Space
O(1)
Where the time goes
  • Inspect midpoint and classify sorted halfA fixed number of comparisons.O(1)
  • Discard half of the candidatesAt most logarithmically many iterations.dominantO(log n)
  • Store search boundariesOnly scalar indices are needed.O(1)
How it grows
input size n →opsO(n²)O(n log n)O(n)O(log n)O(1)
Roughly what that costs
n101001,00010,000
O(log n)371013
O(n)101001K10K

The method preserves binary-search speed while handling the rotation without extra memory.

Now try it on your own problem

Paste any LeetCode problem — or one of your own — and codebrew builds a walkthrough like this one for it.

Build a lesson from any problem

Related problems