LeetCode #33 — Medium

Search in Rotated
Sorted Array

A complete visual walkthrough of the modified binary search — understanding which half is sorted and where the target hides.

Solve on LeetCode
The Problem

Problem Statement

There is an integer array nums sorted in ascending order (with distinct values).

Prior to being passed to your function, nums is possibly left rotated at an unknown index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be left rotated by 3 indices and become [4,5,6,7,0,1,2].

Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

You must write an algorithm with O(log n) runtime complexity.

Example 1:

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

Example 2:

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

Example 3:

Input: nums = [1], target = 0
Output: -1

Constraints:

  • 1 <= nums.length <= 5000
  • -104 <= nums[i] <= 104
  • All values of nums are unique.
  • nums is an ascending array that is possibly rotated.
  • -104 <= target <= 104
Patterns Used

Roadmap

  1. Brute Force — Linear Scan
  2. The Core Insight — One Half Is Always Sorted
  3. Walkthrough — Visual Pointer Movement
  4. Edge Cases
  5. Full Annotated Code
  6. Interactive Demo
  7. Complexity Analysis
Step 01

Brute Force — Linear Scan

The naive approach ignores the sorted structure entirely: just scan every element until you find the target.

Linear Search

for (int i = 0; i < nums.length; i++) {
    if (nums[i] == target) return i;
}
return -1;

This is O(n) — it works but ignores the fact that the array is nearly sorted. The problem explicitly requires O(log n), which means binary search.

💡

Key question: Standard binary search needs a fully sorted array. A rotated array has a "break point." How can we still use binary search? The trick is recognizing that at least one half is always sorted.

Step 02

The Core Insight — One Half Is Always Sorted

When you pick the midpoint of a rotated sorted array, the rotation break can only be in one half. The other half is guaranteed to be perfectly sorted.

Visualizing the Rotation

Array [4, 5, 6, 7, 0, 1, 2] — rotated at index 4. The values form a "broken staircase":

4
5
6
7
0
1
2

The left segment [4,5,6,7] is sorted. The right segment [0,1,2] is also sorted. The break is between them.

The Decision at Each Step

if nums[lo] <= nums[mid] → left half is sorted
Check if target falls in [nums[lo], nums[mid]). If yes, search left. Otherwise search right.
else → right half is sorted
Check if target falls in (nums[mid], nums[hi]]. If yes, search right. Otherwise search left.

Why does this work? In the sorted half, we can definitively say whether the target is there (it must be within its range). If the target is not in the sorted half, it must be in the other half — the one containing the rotation break.

Step 03

Walkthrough — Visual Pointer Movement

Let's trace nums = [4,5,6,7,0,1,2], target = 0 step by step.

Iteration-by-Iteration Trace

Iterlohimidnums[mid]Sorted HalfAction
10637 Left [4,5,6,7] target=0 not in [4,7] → lo = 4
24651 Right [1,2] target=0 not in (1,2] → hi = 4
34440 Found! return 4

Visual state at each iteration:

Iteration 1: lo=0, mid=3, hi=6
4lo
5
6
7mid
0
1
2hi
Iteration 2: lo=4, mid=5, hi=6
4
5
6
7
0lo
1mid
2hi
Iteration 3: lo=4, mid=4, hi=4
4
5
6
7
0lo/mid/hi
1
2
Step 04

Edge Cases

Cases to Watch For

Target not found
Binary search exhausts all options (lo > hi). Return -1.
Single element [5], target=5
lo = hi = mid = 0, nums[mid] == target. Return 0.
Not rotated [1,2,3,4,5]
The left half is always sorted. Reduces to standard binary search — still works!
Rotation at boundaries [2,1] or [5,1,2,3,4]
Minimal or maximal rotation. The nums[lo] <= nums[mid] check handles both correctly.
Step 05

Full Annotated Code

class Solution {
    public int search(int[] nums, int target) {
        int lo = 0, hi = nums.length - 1;

        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;

            // Found the target
            if (nums[mid] == target) return mid;

            if (nums[lo] <= nums[mid]) {
                // Left half [lo..mid] is sorted
                if (target >= nums[lo] && target < nums[mid])
                    hi = mid - 1;   // target is in sorted left half
                else
                    lo = mid + 1;   // target is in right half

            } else {
                // Right half [mid..hi] is sorted
                if (target > nums[mid] && target <= nums[hi])
                    lo = mid + 1;   // target is in sorted right half
                else
                    hi = mid - 1;   // target is in left half
            }
        }

        return -1;  // target not found
    }
}
Step 06

Interactive Demo

Enter a rotated sorted array and a target value. Step through to see which half is identified as sorted and how pointers move.

Binary Search Visualizer



Step 07

Complexity Analysis

Time
O(log n)
Space
O(1)

Each iteration halves the search space, just like standard binary search. We perform at most log2(n) comparisons. Only a constant number of pointer variables are used -- no extra data structures needed, giving O(1) space.

Approach Breakdown

BRUTE FORCE
O(n) time
O(1) space

A single for-loop walks through all n elements comparing each to the target. In the worst case (target absent or at the end), every element is visited -- O(n). No auxiliary data structures are used, just one loop index variable.

OPTIMAL
O(log n) time
O(1) space

Modified binary search halves the search space each iteration. At each midpoint, one half is guaranteed sorted; we check if the target falls within that sorted range to decide which half to discard. This yields at most log2(n) iterations. Only three pointer variables (lo, hi, mid) are used.

🎯

At each step, one half is guaranteed sorted -- compare the target with that half's bounds to decide direction. The rotation does not hurt us. Even though the array is not fully sorted, the property that one half is always sorted gives us enough information to discard the other half, preserving the O(log n) guarantee.

Coach Notes

Common Mistakes

Review these before coding to avoid predictable interview regressions.

Wrong sorted-half detection

Wrong move: Using incorrect boundary checks causes binary search to choose the wrong half.

Usually fails on: Pivot-near-ends arrays route search away from the target.

Fix: First detect whether left half is sorted (`nums[lo] <= nums[mid]`) or right half is sorted.

Inclusive boundary mistakes

Wrong move: Mixing `<` and `<=` in range checks drops valid targets at boundaries.

Usually fails on: Target at `lo`, `mid`, or `hi` is skipped.

Fix: Use consistent inclusive/exclusive checks and shrink bounds by `mid ± 1`.

Fallback to linear scan

Wrong move: Switching to scan after uncertain branch defeats logarithmic complexity.

Usually fails on: Large inputs time out due to hidden O(n) path.

Fix: Maintain binary-search invariant each iteration; never scan.