Search Rotated Array

editor-page-cover

Problem Statement

Search for a given number in a sorted array, with unique elements, that has been rotated by some arbitrary number. Return -1 if the number does not exist. Assume that the array does not contain duplicates.

Below is an original array before rotation

widget

After performing rotation on this array 6 times it changes to:

widget

The task is to find a given number in this array.


Hint

  • Linear search is not an acceptable solution
  • Try to solve the problem using binary search

Try it yourself

def binary_search_rotated(arr, key):
#TODO: Write - Your - Code
return -1

Solution

def binary_search_rotated(arr, key):
low = 0
high = len(arr) - 1
while low <= high:
mid = low + (high - low) // 2
if arr[mid] == key:
return mid
if arr[low] <= arr[mid]:
if arr[low] <= key < arr[mid]:
high = mid - 1
else:
low = mid + 1
else:
if arr[mid] < key <= arr[high]:
low = mid + 1
else:
high = mid - 1
return -1
v1 = [6, 7, 1, 2, 3, 4, 5];
print("Key(3) found at: " + str(binary_search_rotated(v1, 3)))
print("Key(6) found at: " + str(binary_search_rotated(v1, 6)))
v2 = [4, 5, 6, 1, 2, 3];
print("Key(3) found at: " + str(binary_search_rotated(v2, 3)))
print("Key(6) found at: " + str(binary_search_rotated(v2, 6)))

Solution Explanation

Runtime complexity

The runtime complexity of this solution is logarithmic, O(logn)O(log n).

Memory complexity

The memory complexity of this solution is constant, O(1)O(1).


Solution Breakdown

To tackle rotation in a binary search for a rotated array, we adjust the search range based on the middle element’s comparisons as follows:

  1. If the element at the middle index matches the target, return the index of the middle element, as the target has been found.

  2. If the element at the middle index is greater than or equal to the element at the start index, it implies that the left subarray (from the start to the middle) is sorted:

    • Now, check if the target falls within the range of elements from the leftmost element to the middle element. If it does, adjust the search range to focus on the left subarray.

    • Otherwise, adjust the search range to focus on the right subarray.

  3. If the element at the middle index is less than the element at the end index, it indicates that the right subarray (from the middle to the end) is sorted:

    • Check if the target falls within the range of elements from the middle element to the rightmost element. If it does, adjust the search range to focus on the right subarray.

    • Otherwise, adjust the search range to focus on the left subarray.

To implement the algorithm:

  1. Initialize low to 0 and high to the length of the array minus one.

  2. Enter a while loop that continues while low is less than or equal to high.

    • Inside the loop, calculate mid using the formula low + (high - low) // 2.

    • Check if the element at the middle index matches the target. If it does, return the index of the middle element.

    • If arr[low] is less than or equal to arr[mid], it implies that the left subarray (from low to mid) is sorted:

      • If the target falls within this range, update the high to mid - 1. Otherwise, update the low to mid + 1.
    • Otherwise, it’s obvious that arr[low] is greater than arr[mid], which it indicates that the right subarray (from mid to high) is sorted:

      • If the target falls within this range, update the low to mid + 1. Otherwise, update the high to mid - 1.
    • If the target is not found after the loop, return -1 to indicate its absence in the array.

Practice problems like this and many more by checking out our Grokking the Coding Interview: Patterns for Coding Questions course!