Search in Rotated Sorted Array – Solution & Complexity

Solution Walkthrough

1. Understanding the Problem

  • The array was sorted ascending, then rotated at some unknown pivot (e.g. [0,1,2,4,5,6,7] rotated at index 3 becomes [4,5,6,7,0,1,2]).
  • You need to find target's index in O(log n) — a plain linear scan is O(n) and defeats the point of the problem.
  • Key insight: even though the whole array isn't sorted, at least one of the two halves around any midpoint always is sorted. That's enough to still binary search.

2. Modified Binary Search

  • Keep lo/hi pointers like standard binary search. At each step compute mid.
  • Determine which half is sorted by comparing nums[lo] and nums[mid]: if nums[lo] <= nums[mid], the left half [lo..mid] is sorted; otherwise the right half [mid..hi] is sorted.
  • Once you know which half is sorted, checking whether target lies within that half's value range is a simple comparison. If it does, search that half; otherwise, search the other half.

3. Working Through the Branches

  • If nums[mid] == target, return mid immediately.
  • If left half [lo..mid] is sorted: target is in it exactly when nums[lo] <= target < nums[mid], so narrow hi = mid - 1; otherwise narrow lo = mid + 1.
  • If the right half [mid..hi] is sorted instead: target is in it exactly when nums[mid] < target <= nums[hi], so narrow lo = mid + 1; otherwise narrow hi = mid - 1.
  • Loop while lo <= hi; if the loop ends without finding target, return -1.

4. Final Solution (all languages)

This still runs in O(log n) time and O(1) space — the halving still happens every iteration, just with an extra comparison to figure out which half is sorted.

def search(nums: list[int], target: int) -> int:
    lo, hi = 0, len(nums) - 1
    while lo <= hi:
        mid = (lo + hi) // 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

5. Common mistakes & interviewer follow-ups

  • Using nums[lo] < nums[mid] instead of <= to detect the sorted half — with only 1-2 elements in a half, lo == mid and the strict inequality misclassifies it as unsorted.
  • Off-by-one errors in the range checks (< vs <= at the boundaries) — easy to skip or double-count the boundary element.
  • Follow-ups: how does the approach change if the array can contain duplicates (values equal to nums[lo] making it ambiguous which half is sorted — worst case degrades to O(n))? How would you find the rotation pivot index itself?

FAQ