Open In App

Rotation Count in a Rotated Sorted array

Last Updated : 09 Oct, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

Given an array arr[] having distinct numbers sorted in increasing order and the array has been right rotated (i.e, the last element will be cyclically shifted to the starting position of the array) k number of times, the task is to find the value of k.

Examples:  

Input: arr[] = {15, 18, 2, 3, 6, 12}
Output: 2
Explanation: Initial array must be {2, 3, 6, 12, 15, 18}. 
We get the given array after rotating the initial array twice.

Input: arr[] = {7, 9, 11, 12, 5}
Output: 4

Input: arr[] = {7, 9, 11, 12, 15};
Output: 0

Naive Approach – O(n) Time and O(1) Space

If we take a closer look at examples, we can notice that the number of rotations is equal to the index of the minimum element. A simple linear solution is to find the minimum element and returns its index. 

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

// Returns count of rotations for an array which
// is first sorted in ascending order, then rotated
int countRotations(vector<int>& arr)
{
    // Find index of minimum element
    int min = arr[0], min_index = 0;
    for (int i = 0; i < arr.size(); i++) {
        if (min > arr[i]) {
            min = arr[i];
            min_index = i;
        }
    }
    return min_index;
}

// Driver code
int main()
{
    vector<int> arr = { 15, 18, 2, 3, 6, 12 };
    cout << countRotations(arr);
    return 0;
}
C Java Python C# JavaScript PHP

Output
2

Expected Approach – O(Log n) Time and O(1) Space

As we have seen above, this problem is mainly a variation find the smallest element in the array. The only change here is, we need to find the index of the minimum element instead of the value.

In Binary Search, we find the mid element and then decide whether to stop or to go to left half or right half. How do we decide in this case. Let us take few examples.

{4, 5, 6, 9, 0, 1, 2}, mid = (0 + 7) / 2 = 3. arr[3] is 9. How do find out that we need to go to the right half (Note that the smallest element is in right half)? We can say if arr[mid] > arr]high], then we go the right half. So we change low = mid + 1.

{50, 10, 20, 30, 40}, mid = (0 + 4)/2 = 2. arr[2] is 20. If arr[mid] is smaller than or equal to arr[high], then we go to the left half.

How do we terminate the search? One way could be to check if the mid is smaller than both of its adjacent, then we return mid. This would require a lot of condition checks like if adjacent indexes are valid or not and then comparing mid with both. We use an interesting fact here. If arr[low] <= arr[high], then the current subarray must be sorted, So we return arr[low]. This optimizes the code drastically as we do not have to explicitly check the whole sorted array.

Below is the implementation of the above approach.

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

int findMin(vector<int> &arr)
{
    int low = 0, high = arr.size() - 1;

    while (low < high)
    {
        // The current subarray is already sorted, 
        // the minimum is at the low index
        if (arr[low] <= arr[high])        
            return low;
           
        // We reach here when we have at least
        // two elements and the current subarray
        // is rotated
      
        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. Ad the mid element
        // etself can be the smallest
        else
            high = mid;
    }

    return low; 
}

// Driver program to test above functions
int main()
{
    vector<int> arr = {5, 6, 1, 2, 3, 4};
    cout << findMin(arr);
    return 0;
}
Java Python C# JavaScript PHP

Output
2





Next Article

Similar Reads

three90RightbarBannerImg