Check if an array is sorted and rotated using Binary Search - GeeksforGeeks

21 Aug, 2021
Pre-requisite: Check if an array is sorted and rotated using Linear SearchGiven an array arr[] of N distinct integers, the task is to check if this array is sorted when rotated counter-clockwise. A sorted array is not considered sorted and rotated, i.e., there should at least one rotation.
Examples: 
Input: arr[] = { 3, 4, 5, 1, 2 } Output: true Explanation: Sorted array: {1, 2, 3, 4, 5}. Rotating this sorted array clockwise by 3 positions, we get: { 3, 4, 5, 1, 2}
Input: arr[] = {7, 9, 11, 12, 5} Output: true
Input: arr[] = {1, 2, 3} Output: false 
Approach: One approach to solving this problem using Linear Search has already been discussed in this article. In this article, an approach using Binary Search concept is mentioned. 
To apply a binary search, the array needs to follow some order by which at every iteration, one-half of the array can be eliminated.
Therefore, the order followed by an array which is sorted and rotated array is that all the elements to the left of the pivot(the point at which the array is rotated) are in descending order and all the elements to the right of the pivot would be in ascending order. This can be visualized from the illustration below: 
Therefore, the pivot can be found using Binary Search and recursion in the following way: Base Cases: The base case will be either when the pivot has been found or if the pivot cannot be found in the given array. The pivot cannot be found when the right index is less than the left index. -1 is returned in these cases. And when high and low are pointing to the same element, then the element at low is the pivot and that element is returned.
Base Cases: The base case will be either when the pivot has been found or if the pivot cannot be found in the given array. The pivot cannot be found when the right index is less than the left index. -1 is returned in these cases. And when high and low are pointing to the same element, then the element at low is the pivot and that element is returned.
if (high < low)
     return -1;
if (high == low)
     return low;
Apart from this, another base case is when mid((low + high) / 2) is a pivot. The element at mid is considered when that element is less than the next element or greater than the previous element.
if (mid < high && arr[mid + 1] < arr[mid])
    return mid;
if (mid > low && arr[mid] < arr[mid - 1])
    return mid - 1;
Recursive Case: When none of the base cases satisfies, then a decision has to be made whether to ignore the first half or second half. This decision is taken by checking if the element at the first index (low) is greater than the element at the middle index or not. If it is, then the pivot for sure lies in the first half. Else, the pivot lies in the second half.
if (arr[low] > arr[mid]) 
    return findPivot(arr, low, mid - 1);    
else 
    return findPivot(arr, mid + 1, high);
Once the pivot is found, then either traverse to the left of the array from the pivot and check if all the elements are in descending order, or traverse to the right of the array and check if all the elements are in ascending order or not.
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
#include <bits/stdc++.h> using namespace std; // Function to return the// index of the pivotint findPivot(int arr[], int low, int high){    // Base cases    if (high < low)        return -1;    if (high == low)        return low;     int mid = (low + high) / 2;    if (mid < high && arr[mid + 1] < arr[mid])    {        return mid;    }     // Check if element at (mid - 1) is pivot    // Consider the cases like {4, 5, 1, 2, 3}    if (mid > low && arr[mid] < arr[mid - 1])    {        return mid - 1;    }     // Decide whether we need to go to    // the left half or the right half    if (arr[low] > arr[mid])    {        return findPivot(arr, low, mid - 1);    }    else    {        return findPivot(arr, mid + 1, high);    }} // Function to check if a given array// is sorted rotated or notbool isRotated(int arr[], int n){    int l = 0;    int r = n - 1;    int pivot = -1;    if (arr[l] > arr[r])    {        pivot = findPivot(arr, l, r);        int temp=pivot;        // To check if the elements to the left        // of the pivot are in descending or not        if (l < pivot)        {            while (pivot > l)            {                if (arr[pivot] < arr[pivot - 1])                {                    return false;                }                pivot--;            }        }         // To check if the elements to the right        // of the pivot are in ascending or not        pivot=temp;        if(pivot < r) {            pivot++;            while (pivot < r) {                if (arr[pivot] > arr[pivot + 1]) {                    return false;                }                pivot++;            }        }         // If both of the above if is true        // Then the array is sorted rotated        return true;    }     // Else the array is not sorted rotated    else {        return false;    }} // Driver codeint main(){    int arr[] = { 4, 5, 1, 3, 2 };    if (isRotated(arr, 5)) cout<<"true";    else    cout<<"false";    return 0;} // This code is contributed by mohit kumar 29
// Java implementation of the above approach class GFG {     // Function to return the    // index of the pivot    static int findPivot(int arr[], int low, int high)    {        // Base cases        if (high < low)            return -1;        if (high == low)            return low;         int mid = (low + high) / 2;        if (mid < high && arr[mid + 1] < arr[mid]) {            return mid;        }         // Check if element at (mid - 1) is pivot        // Consider the cases like {4, 5, 1, 2, 3}        if (mid > low && arr[mid] < arr[mid - 1]) {            return mid - 1;        }         // Decide whether we need to go to        // the left half or the right half        if (arr[low] > arr[mid]) {            return findPivot(arr, low, mid - 1);        }        else {            return findPivot(arr, mid + 1, high);        }    }     // Function to check if a given array    // is sorted rotated or not    public static boolean isRotated(int arr[], int n)    {        int l = 0;        int r = n - 1;        int pivot = -1;        if (arr[l] > arr[r]) {            pivot = findPivot(arr, l, r);            int temp=pivot;            // To check if the elements to the left            // of the pivot are in descending or not            if (l < pivot) {                while (pivot > l) {                    if (arr[pivot] < arr[pivot - 1]) {                        return false;                    }                    pivot--;                }            }             // To check if the elements to the right            // of the pivot are in ascending or not                       pivot=temp;            else {                pivot++;                while (pivot < r) {                    if (arr[pivot] > arr[pivot + 1]) {                        return false;                    }                    pivot++;                }            }             // If any of the above if or else is true            // Then the array is sorted rotated            return true;        }         // Else the array is not sorted rotated        else {            return false;        }    }     // Driver code    public static void main(String[] args)    {        int arr[] = {  4, 5, 1, 3, 2 };        System.out.println(isRotated(arr, 5));    }}
# Python3 implementation of the above approach # Function to return the# index of the pivotdef findPivot(arr, low, high) :     # Base cases    if (high < low) :        return -1;             if (high == low) :        return low;     mid = (low + high) // 2;    if (mid < high and arr[mid + 1] < arr[mid]) :             return mid;     # Check if element at (mid - 1) is pivot    # Consider the cases like {4, 5, 1, 2, 3}    if (mid > low and arr[mid] < arr[mid - 1]) :             return mid - 1;         # Decide whether we need to go to    # the left half or the right half    if (arr[low] > arr[mid]) :             return findPivot(arr, low, mid - 1);         else :             return findPivot(arr, mid + 1, high);     # Function to check if a given array# is sorted rotated or notdef isRotated(arr, n) :     l = 0;    r = n - 1;    pivot = -1;    if (arr[l] > arr[r]) :             pivot = findPivot(arr, l, r);        temp = pivot        # To check if the elements to the left        # of the pivot are in descending or not                 if (l < pivot) :                     while (pivot > l) :                             if (arr[pivot] < arr[pivot - 1]) :                                     return False;                                 pivot -= 1;         # To check if the elements to the right        # of the pivot are in ascending or not                 else :            pivot=temp            pivot += 1;            while (pivot < r) :                if (arr[pivot] > arr[pivot + 1]) :                    return False;                                 pivot ++ 1;             # If any of the above if or else is true        # Then the array is sorted rotated        return True;     # Else the array is not sorted rotated    else :        return False;  # Driver codeif __name__ == "__main__" :     arr = [ 3, 4, 5, 1, 2 ];    if (isRotated(arr, 5)) :        print("True");    else :        print("False"); # This code is contributed by Yash_R
// C# implementation of the above approachusing System; class GFG {      // Function to return the    // index of the pivot    static int findPivot(int []arr, int low, int high)    {        // Base cases        if (high < low)            return -1;        if (high == low)            return low;          int mid = (low + high) / 2;        if (mid < high && arr[mid + 1] < arr[mid]) {            return mid;        }          // Check if element at (mid - 1) is pivot        // Consider the cases like {4, 5, 1, 2, 3}        if (mid > low && arr[mid] < arr[mid - 1]) {            return mid - 1;        }          // Decide whether we need to go to        // the left half or the right half        if (arr[low] > arr[mid]) {            return findPivot(arr, low, mid - 1);        }        else {            return findPivot(arr, mid + 1, high);        }    }      // Function to check if a given array    // is sorted rotated or not    public static bool isRotated(int []arr, int n)    {        int l = 0;        int r = n - 1;        int pivot = -1;        if (arr[l] > arr[r]) {            pivot = findPivot(arr, l, r);            int temp = pivot;            // To check if the elements to the left            // of the pivot are in descending or not            if (l < pivot) {                while (pivot > l) {                    if (arr[pivot] < arr[pivot - 1]) {                        return false;                    }                    pivot--;                }            }              // To check if the elements to the right            // of the pivot are in ascending or not            pivot=temp;            else {                pivot++;                while (pivot < r) {                    if (arr[pivot] > arr[pivot + 1]) {                        return false;                    }                    pivot++;                }            }              // If any of the above if or else is true            // Then the array is sorted rotated            return true;        }          // Else the array is not sorted rotated        else {            return false;        }    }      // Driver code    public static void Main(String[] args)    {        int []arr = { 3, 4, 5, 1, 2 };        Console.WriteLine(isRotated(arr, 5));    }} // This code contributed by Rajput-Ji
<script> // Function to return the// index of the pivotfunction findPivot(arr, low, high){    // Base cases    if (high < low)        return -1;    if (high == low)        return low;     var mid = parseInt((low + high) / 2);    if (mid < high && arr[mid + 1] < arr[mid])    {        return mid;    }     // Check if element at (mid - 1) is pivot    // Consider the cases like {4, 5, 1, 2, 3}    if (mid > low && arr[mid] < arr[mid - 1])    {        return mid - 1;    }     // Decide whether we need to go to    // the left half or the right half    if (arr[low] > arr[mid])    {        return findPivot(arr, low, mid - 1);    }    else    {        return findPivot(arr, mid + 1, high);    }} // Function to check if a given array// is sorted rotated or notfunction isRotated(arr, n){    var l = 0;    var r = n - 1;    var pivot = -1;    if (arr[l] > arr[r])    {        pivot = findPivot(arr, l, r);        var temp=pivot;        // To check if the elements to the left        // of the pivot are in descending or not        if (l < pivot)        {            while (pivot > l)            {                if (arr[pivot] < arr[pivot - 1])                {                    return false;                }                pivot--;            }        }         // To check if the elements to the right        // of the pivot are in ascending or not                 else        {            pivot=temp;            pivot++;            while (pivot < r) {                if (arr[pivot] > arr[pivot + 1]) {                    return false;                }                pivot++;            }        }         // If both of the above if is true        // Then the array is sorted rotated        return true;    }     // Else the array is not sorted rotated    else {        return false;    }} // Driver codevar arr = [4, 5, 1, 3, 2];if (isRotated(arr, 5))    document.write("true");else    document.write("false"); </script>
true
 
Time Complexity: O(N) as: 
The pivot element is being found using Binary Search in O(log N)
But in order to check if the left part or right part is in descending or ascending order, O(N) time is needed in worst case scenario.
Therefore the overall time complexity is O(N)
 
mohit kumar 29
Rajput-Ji
Yash_R
anushka128
rrrtnx
sumitgumber28
Binary Search
Arrays
Recursion
Searching
Arrays
Searching
Recursion
Binary Search
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Stack Data Structure (Introduction and Program)
Introduction to Arrays
Multidimensional Arrays in Java
Write a program to print all permutations of a given string
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Recursion
Program for Tower of Hanoi
Backtracking | Introduction