ctci/10. Sorting and searching/10.3. Search in rotated arr...

1.6 KiB

10.3. Search in rotated array

Given a sorted array of n integers that has been rotated an unknown number of times, find an element in the array. The array was originally sorted in increasing order.

  • Input: find 5 in {15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14}
  • Output: 8 (the index of 5 in the array)

If the first element is larger than our number, start search from the end. If not, start from the beginning.

def find_in_rotated(ar: list, el: int) -> int:
    ar = ar[::-1] if el < ar[0] else ar
    for i, num in enumerate(ar):
        if el == num:
            return i
    return None

In the worst case scenario it takes O(n/2), O(1) space.

Hints

Modify binary search for this purpose

My implementation was brute force. This one uses binary search and has runtime of O(n)

def rotated_binary_search(arr, key):
    N = len(arr)
    L = 0
    R = N - 1
    while L <= R:
        M = L + ((R - L) / 2)
        if (arr[M] == key):
            return M
        # the bottom half is sorted
        if (arr[L] <= arr[M]):
            if (arr[L] <= key and key < arr[M]):
                R = M - 1
            else:
                L = M + 1
        # the upper half is sorted
        else:
            if (arr[M] < key and key <= arr[R]):
                L = M + 1
            else:
                R = M - 1
    return -1

arr = [15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14]
x = 10
result = rotated_binary_search(arr, x)

If there are duplicates, the runtime might be O(n) because we will have to search both the left and right sides of the array.