Search in a sorted and rotated Array

Spread the love
Close-up of a computer screen displaying programming code in a dark environment.

Given a sorted and rotated array arr[] of n unique entries, the goal is to locate the index of specified key in the array. Return -1 should the key not be found in the array.

Examples

Input  : arr[] = {4, 5, 6, 7, 0, 1, 2}, key = 0
Output : 4


Input  : arr[] = { 4, 5, 6, 7, 0, 1, 2 }, key = 3
Output : -1


Input : arr[] = {50, 10, 20, 30, 40}, key = 10   
Output : 1

Using Two Binary Searches

For instance, the min in {4, 5, 6, 7, 0, 1, 2} is 0 at index 4. Find the pivot point—or index of the min element. And at index 1 the min of 50, 10, 20, 30, 40 equals 10. How to get the min’s index? We have covered in great length here.

Once we identify the pivot, we may readily split the provided array into two sorted subarrays with the index of the min. For instance {{4, 5, 6, 7, 0, 1, 2} as {{4, 5, 6, 7}, {1, 2}} and {{50, 10, 20, 30, 40} as {{50}, {10, 20, 30, 40} }. The following are the arising cases:

Should the provided key match minimal, we return
Should min index be zero, the entire array is sorted; hence, we use binary search over the complete array.
How then should we choose the subarray in other circumstances? To call binary search for both sides, one basic concept is We can save one binary search even though the general time complexity will remain O(Log n). One intends to match the given key with the first element. For instance {{4, 5, 6, 7}, {1, 2}, and with a key = 6. We conduct binary search in the first subarray if key is more than equal to the first element; else, in the second.

C++

#include <bits/stdc++.h>
using namespace std;

// An iterative binary search function.
int binarySearch(vector<int> &arr, int low, int high, int x) {
    while (low <= high) {
        int mid = low + (high - low) / 2;
        if (arr[mid] == x) return mid;
        if (arr[mid] < x) low = mid + 1;
        else high = mid - 1;
    }
    return -1;
}

// Function to get pivot. For array 3, 4, 5, 6, 1, 2
// it returns 4 (index of 1)
int findPivot(vector<int> &arr, int low, int high) {
    while (low < high) {
      
        // The current subarray is already sorted,
        // the minimum is at the low index
        if (arr[low] <= arr[high])        
            return low;
        
        int mid = (low + high) / 2;

        // The right half is not sorted. So
        // the minimum element must be in the
        // right half.
        if (arr[mid] > arr[high])
            low = mid + 1;
        // The right half is sorted. Note that in
        // this case, we do not change high to mid - 1
        // but keep it to mid. The mid element
        // itself can be the smallest
        else
            high = mid;
    }

    return low;
}

// Searches an element key in a pivoted
// sorted array arr of size n
int pivotedBinarySearch(vector<int> &arr, int n, int key) {
    int pivot = findPivot(arr, 0, n - 1);

    // If the minimum element is present at index
    // 0, then the whole array is sorted
    if (pivot == 0)
        return binarySearch(arr, 0, n - 1, key);

    // If we found a pivot, then first compare with pivot
    // and then search in two subarrays around pivot
    if (arr[pivot] == key)
        return pivot;

    if (arr[0] <= key)
        return binarySearch(arr, 0, pivot - 1, key);
    return binarySearch(arr, pivot + 1, n - 1, key);
}

// Driver program to check above functions
int main() {
    // Let us search 3 in below array
    vector<int> arr = {5, 6, 7, 8, 9, 10, 1, 2, 3};
    int key = 3;
    cout << pivotedBinarySearch(arr, arr.size(), key);
    return 0;
}

Java

import java.util.Arrays;

public class Main {
    // An iterative binary search function.
    public static int binarySearch(int[] arr, int low, int high, int x) {
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (arr[mid] == x) return mid;
            if (arr[mid] < x) low = mid + 1;
            else high = mid - 1;
        }
        return -1;
    }

    // Function to get pivot. For array 3, 4, 5, 6, 1, 2
    // it returns 4 (index of 1)
    public static int findPivot(int[] arr, int low, int high) {
        while (low < high) {
            // The current subarray is already sorted,
            // the minimum is at the low index
            if (arr[low] <= arr[high])
                return low;
            
            int mid = (low + high) / 2;
            // The right half is not sorted. So
            // the minimum element must be in the
            // right half.
            if (arr[mid] > arr[high])
                low = mid + 1;
            // The right half is sorted. Note that in
            // this case, we do not change high to mid - 1
            // but keep it to mid. The mid element
            // itself can be the smallest
            else
                high = mid;
        }
        return low;
    }

    // Searches an element key in a pivoted
    // sorted array arr of size n
    public static int pivotedBinarySearch(int[] arr, int n, int key) {
        int pivot = findPivot(arr, 0, n - 1);

        // If the minimum element is present at index
        // 0, then the whole array is sorted
        if (pivot == 0)
            return binarySearch(arr, 0, n - 1, key);

        // If we found a pivot, then first compare with pivot
        // and then search in two subarrays around pivot
        if (arr[pivot] == key)
            return pivot;

        if (arr[0] <= key)
            return binarySearch(arr, 0, pivot - 1, key);
        return binarySearch(arr, pivot + 1, n - 1, key);
    }

    // Driver program to check above functions
    public static void main(String[] args) {
        // Let us search 3 in below array
        int[] arr = {5, 6, 7, 8, 9, 10, 1, 2, 3};
        int key = 3;
        System.out.println(pivotedBinarySearch(arr, arr.length, key));
    }
}

Python

def binary_search(arr, low, high, x):
    # An iterative binary search function.
    while low <= high:
        mid = low + (high - low) // 2
        if arr[mid] == x:
            return mid
        if arr[mid] < x:
            low = mid + 1
        else:
            high = mid - 1
    return -1

def find_pivot(arr, low, high):
    # Function to get pivot. For array 3, 4, 5, 6, 1, 2 it returns 4 (index of 1) 
    while low < high:
        # The current subarray is already sorted, the minimum is at the low index
        if arr[low] <= arr[high]:
            return low
        
        mid = (low + high) // 2
        # The right half is not sorted. So the minimum element must be in the right half.
        if arr[mid] > arr[high]:
            low = mid + 1
        # The right half is sorted. Note that in this case, we do not change high to mid - 1
        # but keep it to mid. The mid element itself can be the smallest
        else:
            high = mid
    return low

def pivoted_binary_search(arr, n, key):
    #Searches an element key in a pivoted sorted array arr of size n 
    pivot = find_pivot(arr, 0, n - 1)

    # If the minimum element is present at index 0, then the whole array is sorted
    if pivot == 0:
        return binary_search(arr, 0, n - 1, key)

    # If we found a pivot, then first compare with pivot and then search in two subarrays around pivot
    if arr[pivot] == key:
        return pivot

    if arr[0] <= key:
        return binary_search(arr, 0, pivot - 1, key)
    return binary_search(arr, pivot + 1, n - 1, key)

# Driver program to check above functions
if __name__ == "__main__":
    # Let us search 3 in below array
    arr = [5, 6, 7, 8, 9, 10, 1, 2, 3]
    key = 3
    print(pivoted_binary_search(arr, len(arr), key))

C#

using System;

class Program {
    // An iterative binary search function.
    static int BinarySearch(int[] arr, int low, int high, int x) {
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (arr[mid] == x) return mid;
            if (arr[mid] < x) low = mid + 1;
            else high = mid - 1;
        }
        return -1;
    }

    // Function to get pivot. For array 3, 4, 5, 6, 1, 2
    // it returns 4 (index of 1)
    static int FindPivot(int[] arr, int low, int high) {
        while (low < high) {
            // The current subarray is already sorted,
            // the minimum is at the low index
            if (arr[low] <= arr[high])
                return low;
            
            int mid = (low + high) / 2;
            // The right half is not sorted. So
            // the minimum element must be in the
            // right half.
            if (arr[mid] > arr[high])
                low = mid + 1;
            // The right half is sorted. Note that in
            // this case, we do not change high to mid - 1
            // but keep it to mid. The mid element
            // itself can be the smallest
            else
                high = mid;
        }
        return low;
    }

    // Searches an element key in a pivoted
    // sorted array arr of size n
    static int PivotedBinarySearch(int[] arr, int n, int key) {
        int pivot = FindPivot(arr, 0, n - 1);

        // If the minimum element is present at index
        // 0, then the whole array is sorted
        if (pivot == 0)
            return BinarySearch(arr, 0, n - 1, key);

        // If we found a pivot, then first compare with pivot
        // and then search in two subarrays around pivot
        if (arr[pivot] == key)
            return pivot;

        if (arr[0] <= key)
            return BinarySearch(arr, 0, pivot - 1, key);
        return BinarySearch(arr, pivot + 1, n - 1, key);
    }

    // Driver program to check above functions
    static void Main(string[] args) {
        // Let us search 3 in below array
        int[] arr = {5, 6, 7, 8, 9, 10, 1, 2, 3};
        int key = 3;
        Console.WriteLine(PivotedBinarySearch(arr, arr.Length, key));
    }
}

JavaScript

// An iterative binary search function.
function binarySearch(arr, low, high, x) {
    while (low <= high) {
        let mid = low + Math.floor((high - low) / 2);
        if (arr[mid] === x) return mid;
        if (arr[mid] < x) low = mid + 1;
        else high = mid - 1;
    }
    return -1;
}

// Function to get pivot. For array 3, 4, 5, 6, 1, 2
// it returns 4 (index of 1)
function findPivot(arr, low, high) {
    while (low < high) {
        // The current subarray is already sorted,
        // the minimum is at the low index
        if (arr[low] <= arr[high])
            return low;
        
        let mid = Math.floor((low + high) / 2);
        // The right half is not sorted. So
        // the minimum element must be in the
        // right half.
        if (arr[mid] > arr[high])
            low = mid + 1;
        // The right half is sorted. Note that in
        // this case, we do not change high to mid - 1
        // but keep it to mid. The mid element
        // itself can be the smallest
        else
            high = mid;
    }
    return low;
}

// Searches an element key in a pivoted
// sorted array arr of size n
function pivotedBinarySearch(arr, n, key) {
    let pivot = findPivot(arr, 0, n - 1);

    // If the minimum element is present at index
    // 0, then the whole array is sorted
    if (pivot === 0)
        return binarySearch(arr, 0, n - 1, key);

    // If we found a pivot, then first compare with pivot
    // and then search in two subarrays around pivot
    if (arr[pivot] === key)
        return pivot;

    if (arr[0] <= key)
        return binarySearch(arr, 0, pivot - 1, key);
    return binarySearch(arr, pivot + 1, n - 1, key);
}

// Driver program to check above functions
function main() {
    // Let us search 3 in below array
    const arr = [5, 6, 7, 8, 9, 10, 1, 2, 3];
    const key = 3;
    console.log(pivotedBinarySearch(arr, arr.length, key));
}

main();