Problem Statement
Given an integer array nums of size n, sorted in ascending order with distinct values. The array has been right rotated an unknown number of times, between 1 and n. Determine the number of rotations performed on the array.
Examples
Example 1:
Input: nums = [4, 5, 6, 7, 0, 1, 2, 3]
Output: 4
Explanation: The original array should be [0, 1, 2, 3, 4, 5, 6, 7]. So we can notice that the array has been roated 4 times.
Input 2:
Input: nums = [3, 4, 5, 6, 1]
Output: 1
Explanation: The original array should be [1, 3, 4, 5, 6]. So, we can notice that the array has been roated 1 time.
Different Approaches
1️⃣ Brute Force (Linear Search)
Intuition:
The straightforward solution to this problem involves performing a simple linear search to find the minimum element of the array by comparing each element individually. The index at which the minimum element is found corresponds to the number of times the array has been rotated. Since the array was initially sorted, the smallest element would have been at the front. Therefore, the index of this smallest element gives the number of rotations because it indicates how many positions the array has been shifted.
Approach:
- First, declare an
ans
and an index variable initialized with aINT_MAX
and-1
respectively. - Next, iterate through the array and compare each element with the variable called
ans
. Whenever an element is encountered such that it is smaller thanans
, updateans
with that value and also update theindex
variable with the current index. - Finally, we will return
index
as our answer.
Dry Run:
Initialization:
minimum = INT_MAX
index = -1
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
First Iteration:
minimum = INT_MAX
index = -1
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
^
|
i
If arr[index] < minimum
True
set minimum = min(minimum, arr[index])
minimum = min(INT_MAX, 3)
minimum = 3
index = i
index = 0
i++
Second Iteration:
minimum = 3
index = 0
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
^
|
i
If arr[index] < minimum
False
i++
Third Iteration:
minimum = 3
index = 0
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
^
|
i
If arr[index] < minimum
False
i++
Fourth Iteration:
minimum = 3
index = 0
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
^
|
i
If arr[index] < minimum
True
set minimum = min(minimum, arr[index])
minimum = min(3, 1)
minimum = 1
index = i
index = 3
i++
Fifth Iteration:
minimum = 1
index = 3
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
^
|
i
If arr[index] < minimum
False
i++
Loop Termination:
minimum = 1
index = 3
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
As i exceeds the bounds of the array,
So loop will terminate
and return index (3), which means
this is rotated to right three times.
Code:
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to find the number of
rotations in a rotated sorted array */
int findKRotation(vector<int>& nums) {
// Get the size of the array
int n = nums.size();
/* Initialize variables to store
minimum value and its index*/
int ans = INT_MAX, index = -1;
/* Iterate through the array to
find the smallest element */
for (int i = 0; i < n; i++) {
if (nums[i] < ans) {
ans = nums[i];
index = i;
}
}
// Return the index of smallest element
return index;
}
};
int main() {
vector<int> nums = {4, 5, 6, 7, 0, 1, 2, 3};
// Create an object of the Solution class
Solution sol;
int ans = sol.findKRotation(nums);
// Print the result
cout << "The array is rotated " << ans << " times.\n";
return 0;
}
Complexity Analysis:
- Time Complexity:
O(N)
, whereN
is size of the array. As the array is being traversed only once using a single loop. - Space Complexity: As no additional space is used, so the Space Complexity is
O(1)
.
2️⃣ Optimal (Binary Search)
Intuition:
The idea here is to use the binary search algorithm to determine the index at which the minimum element of the array is located. This index will indicate the number of times the array has been rotated. Observing this, it's analogous to finding the minimum element in a rotated sorted array. Here, the additional requirement is to return the index of the minimum element rather than the element itself.
Approach:
- First, initialize few variables:
low to 0
(beginning of the array,high to (end of the array)
,ans to Integer MAX_VALUE
to track the minimum element found during the search,index to -1
to store the index of the minimum element. - Use a binary search strategy to efficiently find the minimum element in the rotated sorted array, which directly gives the number of rotations. While low is less than or equal to high, calculate the middle index mid.
- If element at
low
is less than or equal to element athigh
, the search space is already sorted. In this case, element atlow
is the smallest element, representing the start of the rotation. Updateans
andindex
accordingly and break out of the loop. - Determine whether the left part of the array is sorted or the right part of the array is sorted
- If the left part is sorted (element at (low) <= element at (mid)):
- Check if element at (low) is less than
ans
. If so, updateans
andindex
to reflect the new minimum element found. - Adjust
low
tomid + 1
to search the right half, as the rotation point (minimum element) must be on the right side.
- Check if element at (low) is less than
- If the right part is sorted (element at (low) > element at (mid)):
- Check if element at (mid) is less than
ans
. If so, updateans
andindex
accordingly. - Adjust
high
tomid - 1
to search the left half.
- Check if element at (mid) is less than
- Once the loop completes,
index
will hold the index of the minimum element, which represents the number of rotations. Returnindex
as the answer.
Dry Run:
Initialization:
minimum = INT_MAX
index = -1
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
First Iteration:
minimum = INT_MAX
index = -1
Left = 0
Right = 4
Mid = Left + (Right - Left) / 2
= 0 + (4 - 0) / 2
= 4 / 2
= 2
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
^ ^ ^
| | |
Left Mid Right
Is arr[Left] <= arr[Right]
3 <= 2
False, this means array is not sorted at complete.
Is arr[Left] <= arr[Mid]
3 <= 5
True
If arr[Left] < minimum
3 < INT_MAX
True
Set minimum = arr[Left]
minimum = 3
index = Left
index = 0
// Go to Right side now (Eliminate Left Half)
Left = Mid + 1
= 2 + 1
= 3
Second Iteration:
minimum = 3
index = 0
Left = 3
Right = 4
Mid = Left + (Right - Left) / 2
= 3 + (4 - 3) / 2
= 3 + 1/ 2
= 3 + 0
= 3
+-----+-----+-----+-----+-----+
arr | 3 | 4 | 5 | 1 | 2 |
+-----+-----+-----+-----+-----+
0 1 2 3 4
^ ^
| |
Left Right
Mid
Is arr[Left] <= arr[Right]
1 <= 2
True, this means array is sorted at complete.
If arr[Left] < minimum
1 < 3
True
Set minimum = arr[Left]
minimum = 1
index = Left
index = 3
Since this part of the array was sorted
and we set the very extreme left element
to the minimum.
Now we no further need to check again.
So break the loop
and return index, which is 3.
Code:
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to find the number of
rotations in a rotated sorted array */
int findKRotation(vector<int>& nums) {
int low = 0, high = nums.size() - 1;
int ans = INT_MAX;
int index = -1;
while (low <= high) {
int mid = (low + high) / 2;
/* Search space is already sorted
then nums[low] will always be
the minimum in that search space */
if (nums[low] <= nums[high]) {
if (nums[low] < ans) {
index = low;
ans = nums[low];
}
break;
}
// If left part is sorted update the ans
if (nums[low] <= nums[mid]) {
if (nums[low] < ans) {
index = low;
ans = nums[low];
}
// Eliminate left half
low = mid + 1;
}
else {
/*update the ans if it
is less than nums[mid] */
if (nums[mid] < ans) {
index = mid;
ans = nums[mid];
}
// Eliminate right half
high = mid - 1;
}
}
//Return the index as answer
return index;
}
};
int main() {
vector<int> nums = {4, 5, 6, 7, 0, 1, 2, 3};
// Create an object of the Solution class
Solution sol;
int ans = sol.findKRotation(nums);
// Print the result
cout << "The array is rotated " << ans << " times.\n";
return 0;
}
Complexity Analysis:
- Time Complexity:
O(logN)
, whereN
is size of the array. As binary search algorithm is being applied to solve the problem. - Space Complexity: As no additional space is used, so the Space Complexity is
O(1)
.