33. Search In Rotated Sorted Array - Explanation

Problem Link

Description

You are given an array of length n which was originally sorted in ascending order. It has now been rotated between 1 and n times. For example, the array nums = [1,2,3,4,5,6] might become:

  • [3,4,5,6,1,2] if it was rotated 4 times.
  • [1,2,3,4,5,6] if it was rotated 6 times.

Given the rotated sorted array nums and an integer target, return the index of target within nums, or -1 if it is not present.

You may assume all elements in the sorted rotated array nums are unique,

A solution that runs in O(n) time is trivial, can you write an algorithm that runs in O(log n) time?

Example 1:

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

Output: 4

Example 2:

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

Output: -1

Constraints:

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


Topics

Recommended Time & Space Complexity

You should aim for a solution with O(logn) time and O(1) space, where n is the size of the input array.


Hint 1

A brute force solution would be to do a linear search on the array to find the target element. This would be an O(n) solution. Can you think of a better way? Maybe an efficient searching algorithm is helpful.


Hint 2

Given that the array is rotated after sorting, elements from the right end are moved to the left end one by one, creating two sorted segments separated by a deflection point due to the rotation. For example, consider the array [3, 4, 1, 2], which is rotated twice, resulting in two sorted segments: [3, 4] and [1, 2]. In a fully sorted array, it's easy to find the target. So, if you can identify the deflection point (cut), you can perform a binary search on both segments to find the target element. Can you use binary search to find this cut?


Hint 3

We perform a binary search on the array with pointers l and r, which belong to two different sorted segments. For example, in [3, 4, 5, 6, 1, 2, 3], l = 0, r = 6, and mid = 3. At least two of l, mid, and r will always be in the same sorted segment. Can you find conditions to eliminate one half and continue the binary search? Perhaps analyzing all possible conditions for l, mid, and r may help.


Hint 4

There are two cases: l and mid belong to the left sorted segment, or mid and r belong to the right sorted segment. If l and mid are in the same segment, nums[l] < nums[mid], so the pivot index must lie in the right part. If mid and r are in the same segment, nums[mid] < nums[r], so the pivot index must lie in the left part. After the binary search, we eventually find the pivot index. Once the pivot is found, it's straightforward to select the segment where the target lies and perform a binary search on that segement to find its position. If we don't find the target, we return -1.


Company Tags

Please upgrade to NeetCode Pro to view company tags.



Prerequisites

Before attempting this problem, you should be comfortable with:

  • Binary Search - The optimal solutions use binary search to achieve O(log n) time complexity
  • Arrays - Understanding array indexing and how rotation affects a sorted array
  • Sorted Array Properties - Recognizing how a rotated sorted array forms two sorted subarrays

1. Brute Force

Intuition

The simplest way to search for a value in an array is to check every element one by one.
If we find the target, we return its index.
If we reach the end without finding it, the target is not present.

This method always works, but it's not efficient for large arrays.

Algorithm

  1. Loop through the array from left to right.
  2. For each index, compare the element with the target.
  3. If they match, return that index.
  4. If the loop finishes without a match, return -1.
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        for i in range(len(nums)):
            if nums[i] == target:
                return i
        return -1

Time & Space Complexity

  • Time complexity: O(n)O(n)
  • Space complexity: O(1)O(1)

Intuition

A rotated sorted array is basically two sorted subarrays joined together.
So the idea is:

  1. Find the pivot — the index of the smallest element.
    This tells us where the rotation happened.

  2. After finding the pivot, the array becomes:

    • A sorted left half
    • A sorted right half
  3. Now we can perform a normal binary search on the correct half where the target could lie.

By combining these two binary searches, we efficiently find the target in logarithmic time.

Algorithm

  1. Use binary search to find the pivot:
    • Compare middle element with the rightmost element.
    • If nums[mid] > nums[right], the pivot is in the right half.
    • Otherwise, it's in the left half.
  2. Once the pivot is identified:
    • The subarray before the pivot is one sorted half.
    • The subarray starting at the pivot is the other sorted half.
  3. Perform a standard binary search on:
    • The left half; if found, return the index.
    • Otherwise, search the right half.
  4. If the target is not in either half, return -1.
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        l, r = 0, len(nums) - 1

        while l < r:
            m = (l + r) // 2
            if nums[m] > nums[r]:
                l = m + 1
            else:
                r = m

        pivot = l

        def binary_search(left: int, right: int) -> int:
            while left <= right:
                mid = (left + right) // 2
                if nums[mid] == target:
                    return mid
                elif nums[mid] < target:
                    left = mid + 1
                else:
                    right = mid - 1
            return -1

        result = binary_search(0, pivot - 1)
        if result != -1:
            return result

        return binary_search(pivot, len(nums) - 1)

Time & Space Complexity

  • Time complexity: O(logn)O(\log n)
  • Space complexity: O(1)O(1)

3. Binary Search (Two Pass)

Intuition

A rotated sorted array is really two sorted arrays stuck together.
So we break the problem into two simple binary searches:

  1. First binary search:
    Find the pivot — the index of the smallest element.
    This tells us where the array was rotated.

  2. Second binary search:
    Decide which sorted half may contain the target,
    then run a standard binary search only on that half.

Algorithm

  1. Use binary search to locate the pivot:
    • Compare middle and right elements.
    • If nums[mid] > nums[right], the pivot is to the right.
    • Otherwise, it's to the left (including mid).
  2. After finding the pivot:
    • If the target lies between nums[pivot] and the last element, search the right half.
    • Otherwise, search the left half.
  3. Perform a standard binary search on the selected half.
  4. Return the index if found, else -1.
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        l, r = 0, len(nums) - 1

        while l < r:
            m = (l + r) // 2
            if nums[m] > nums[r]:
                l = m + 1
            else:
                r = m

        pivot = l
        l, r = 0, len(nums) - 1

        if target >= nums[pivot] and target <= nums[r]:
            l = pivot
        else:
            r = pivot - 1

        while l <= r:
            m = (l + r) // 2
            if nums[m] == target:
                return m
            elif nums[m] < target:
                l = m + 1
            else:
                r = m - 1

        return -1

Time & Space Complexity

  • Time complexity: O(logn)O(\log n)
  • Space complexity: O(1)O(1)

4. Binary Search (One Pass)

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        l, r = 0, len(nums) - 1

        while l <= r:
            mid = (l + r) // 2
            if target == nums[mid]:
                return mid

            if nums[l] <= nums[mid]:
                if target > nums[mid] or target < nums[l]:
                    l = mid + 1
                else:
                    r = mid - 1

            else:
                if target < nums[mid] or target > nums[r]:
                    r = mid - 1
                else:
                    l = mid + 1
        return -1

Time & Space Complexity

  • Time complexity: O(logn)O(\log n)
  • Space complexity: O(1)O(1)

Common Pitfalls

Using Strict Inequality When Comparing with Left Element

In the one-pass binary search, the condition nums[l] <= nums[mid] uses <= rather than <. This handles the edge case when l == mid, which occurs in small subarrays. Using < instead can cause incorrect half selection and miss the target.

Confusing Pivot Finding with Target Finding

The two-pass approach requires finding the pivot first (smallest element), then searching the appropriate half. Do not conflate these steps. The pivot search uses nums[mid] > nums[r] to move left, while the target search is a standard binary search. Mixing the logic leads to wrong results.

Not Handling the Non-Rotated Array Case

When the array is not rotated (or rotated by 0), the pivot is at index 0. Your solution should still work correctly. Test with sorted arrays like [1, 2, 3, 4, 5] to ensure your pivot-finding logic returns index 0 and the subsequent search works.