[06 Aug 2020] Sorted and Rotated Problems
Check if an array is sorted and rotated using Binary Search
Given 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
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.
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]) reutrn 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);
- 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.
- 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:
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)
Comments
Post a Comment