Minimum rotations that have maximum elements with value at most its index
Given an array arr[] of size N, the array can be rotated any number of times such that after rotation, each element of the array arr[] that is less than or equal to its index will get 1 point. The task is to find the rotation index K that corresponds to the highest score. If there are multiple answers, return the smallest among all.
Examples:
Input: arr[] = {2, 3, 1, 4, 0}
Output: 3
Explanation:
k = 0, arr = [2,3,1,4,0], score 2
k = 1, arr = [3,1,4,0,2], score 3 [num index: 3>1, 1==1(1 point), 4>2, 0<3 (1 point), 2<4 (1 point)]
k = 2, arr = [1,4,0,2,3], score 3
k = 3, arr = [4,0,2,3,1], score 4
k = 4, arr = [0,2,3,1,4], score 3
therefore K = 3, gives the highest score.Input: arr[] = {0, 0, 2, 4, 6}
Output: 4
Naive Approach: Calculate the scores for each rotation. Then find the highest score among the total scores calculated and return the lowest index if there are multiple scores.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to rotate the array void rotate(vector< int >& arr, int N) { int temp = arr[0], i; for (i = 0; i < N - 1; i++) arr[i] = arr[i + 1]; arr[N - 1] = temp; return ; } // Function to calculate the // total score of a rotation int calculate(vector< int >& arr) { int score = 0; for ( int i = 0; i < arr.size(); i++) { if (arr[i] <= i) { score++; } } return score; } // Function to find the rotation index k // that corresponds to the highest score int bestIndex(vector< int >& nums) { int N = nums.size(); int high_score = -1; int min_idx = 0; for ( int i = 0; i < N; i++) { if (i != 0) // Rotates the array to left // by one position. rotate(nums, N); // Stores score of current rotation int cur_score = calculate(nums); if (cur_score > high_score) { min_idx = i; high_score = cur_score; } } return min_idx; } // Driver code int main() { vector< int > arr = { 2, 3, 1, 4, 0 }; cout << bestIndex(arr); return 0; } |
Java
// Java program for the above approach import java.io.*; public class GFG { // Function to rotate the array static void rotate( int [] arr, int N) { int temp = arr[ 0 ], i; for (i = 0 ; i < N - 1 ; i++) arr[i] = arr[i + 1 ]; arr[N - 1 ] = temp; return ; } // Function to calculate the // total score of a rotation static int calculate( int [] arr) { int score = 0 ; for ( int i = 0 ; i < arr.length; i++) { if (arr[i] <= i) { score++; } } return score; } // Function to find the rotation index k // that corresponds to the highest score static int bestIndex( int [] nums) { int N = nums.length; int high_score = - 1 ; int min_idx = 0 ; for ( int i = 0 ; i < N; i++) { if (i != 0 ) // Rotates the array to left // by one position. rotate(nums, N); // Stores score of current rotation int cur_score = calculate(nums); if (cur_score > high_score) { min_idx = i; high_score = cur_score; } } return min_idx; } // Driver code public static void main(String args[]) { int [] arr = { 2 , 3 , 1 , 4 , 0 }; System.out.println(bestIndex(arr)); } } // This code is contributed by Saurabh Jaiswal |
Python3
# Python program for the above approach # Function to rotate the array def rotate(arr, N): temp = arr[ 0 ] for i in range ( 0 , N - 1 ): arr[i] = arr[i + 1 ] arr[N - 1 ] = temp return # Function to calculate the # total score of a rotation def calculate(arr): score = 0 for i in range ( 0 , len (arr)): if (arr[i] < = i): score = score + 1 return score # Function to find the rotation index k # that corresponds to the highest score def bestIndex(nums): N = len (nums) high_score = - 1 min_idx = 0 for i in range ( 0 , N): if (i ! = 0 ): # Rotates the array to left # by one position. rotate(nums, N) # Stores score of current rotation cur_score = calculate(nums) if (cur_score > high_score): min_idx = i high_score = cur_score return min_idx # Driver code arr = [ 2 , 3 , 1 , 4 , 0 ] print (bestIndex(arr)) # This code is contributed by Taranpreet |
C#
// C# program for the above approach using System; class GFG { // Function to rotate the array static void rotate( int [] arr, int N) { int temp = arr[0], i; for (i = 0; i < N - 1; i++) arr[i] = arr[i + 1]; arr[N - 1] = temp; return ; } // Function to calculate the // total score of a rotation static int calculate( int [] arr) { int score = 0; for ( int i = 0; i < arr.Length; i++) { if (arr[i] <= i) { score++; } } return score; } // Function to find the rotation index k // that corresponds to the highest score static int bestIndex( int [] nums) { int N = nums.Length; int high_score = -1; int min_idx = 0; for ( int i = 0; i < N; i++) { if (i != 0) // Rotates the array to left // by one position. rotate(nums, N); // Stores score of current rotation int cur_score = calculate(nums); if (cur_score > high_score) { min_idx = i; high_score = cur_score; } } return min_idx; } // Driver code public static void Main() { int [] arr = { 2, 3, 1, 4, 0 }; Console.Write(bestIndex(arr)); } } // This code is contributed by Samim Hossain Mondal. |
Javascript
<script> // JavaScript code for the above approach // Function to rotate the array function rotate(arr, N) { let temp = arr[0], i; for (i = 0; i < N - 1; i++) arr[i] = arr[i + 1]; arr[N - 1] = temp; return arr; } // Function to calculate the // total score of a rotation function calculate(arr) { let score = 0; for (let i = 0; i < arr.length; i++) { if (arr[i] <= i) { score++; } } return score; } // Function to find the rotation index k // that corresponds to the highest score function bestIndex(nums) { let N = nums.length; let high_score = -1; let min_idx = 0; for (let i = 0; i < N; i++) { if (i != 0) // Rotates the array to left // by one position. nums = [...rotate(nums, N)]; // Stores score of current rotation let cur_score = calculate(nums); if (cur_score > high_score) { min_idx = i; high_score = cur_score; } } return min_idx; } // Driver code let arr = [2, 3, 1, 4, 0]; document.write(bestIndex(arr)); // This code is contributed by Potta Lokesh </script> |
3
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient approach: In this approach,
- first calculate the score of input and then make a priority queue (q) in ascending order.
- Then put all non-negative differences of i – arr[i], say diff into the priority queue.
- After this, traverse from 1 to (N -1). Every time the shift is done, since it is a left shift, arr[i-1] becomes the tail of arr, and arr[i-1] becomes arr[N-1].
- Also, all the diff[i] becomes diff[i] -1 by the decrease of map index (caused by left-shift).
- Then score will be changed by 2 cases after each rotation:
Case 1:
arr[i-1] <= N -1, then score++;Case 2:
i > q.front(), then score–because it means the shift makes some diff values become negative (originally which are non-negative).
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to find the rotation index k // that corresponds to the highest score int bestIndex(vector< int >& nums) { int N = nums.size(); int gain = 0; int idx; priority_queue< int , vector< int >, greater< int > > q; for ( int i = 0; i < N; i++) { int diff = i - nums[i]; if (diff >= 0) { gain++; q.push(diff); } } int current = gain; idx = 0; for ( int i = 1; i <= N - 1; i++) { while (!q.empty() && (i > q.top())) { q.pop(); current--; } if (nums[i - 1] <= (N - 1)) { current++; q.push(i + (N - 1) - nums[i - 1]); } if (current > gain) { idx = i; gain = current; } } return idx; } // Driver Code int main() { vector< int > arr = { 2, 3, 1, 4, 0 }; cout << bestIndex(arr); return 0; } |
Java
// Java program for the above approach import java.io.*; public class GFG { // Function to find the rotation index k // that corresponds to the highest score static int bestIndex( int [] nums) { int N = nums.length; int gain = 0 ; int idx = 0 ; PriorityQueue<Integer> q = new PriorityQueue<Integer>(); for ( int i = 0 ; i < N; i++) { int diff = i - nums[i]; if (diff >= 0 ) { gain++; q.add(diff); } } int current = gain; idx = 0 ; for ( int i = 1 ; i <= N - 1 ; i++) { while (q.isEmpty() == false && (i > q.peek())) { q.remove(); current--; } if (nums[i - 1 ] <= (N - 1 )) { current++; q.add(i + (N - 1 ) - nums[i - 1 ]); } if (current > gain) { idx = i; gain = current; } } return idx; } // Driver Code public static void main(String args[]) { int [] arr = { 2 , 3 , 1 , 4 , 0 }; System.out.print(bestIndex(arr)); } } // This code is contributed by Samim Hossain Mondal. |
Python3
# Python code for the above approach import array as arr # Function to find the rotation index k # that corresponds to the highest score def bestIndex(nums): N = len (nums) gain = 0 idx = 0 q = arr.array( 'i' , []) for i in range ( 0 , N): diff = i - nums[i] if diff > = 0 : gain = gain + 1 q.append(diff) current = gain idx = 0 for i in range ( 1 , N): while len (q) = = 0 & (i > (q[ len (q) - 1 ])): q.shift() current = current - 1 if nums[i - 1 ] < = (N - 1 ): current = current + 1 q.append(i + (N - 1 ) - nums[i - 1 ]) if (current > gain): idx = i gain = current return idx - 1 # Driver Code a = arr.array( 'b' , [ 2 , 3 , 1 , 4 , 0 ]) print (bestIndex(a)) # This code is contributed by adityamaharshi21. |
C#
// C# program of the above approach using System; using System.Collections.Generic; class GFG { // Function to find the rotation index k // that corresponds to the highest score static int bestIndex( int [] nums) { int N = nums.Length; int gain = 0; int idx = 0; List< int > q = new List< int >(); for ( int i = 0; i < N; i++) { int diff = i - nums[i]; if (diff >= 0) { gain++; q.Add(diff); q.Sort(); q.Reverse(); } } int current = gain; idx = 0; for ( int i = 1; i <= N - 1; i++) { while (i > q[0]) { q.RemoveAt(0); current--; } if (nums[i - 1] <= (N - 1)) { current++; q.Add(i + (N - 1) - nums[i - 1]); q.Sort(); q.Reverse(); } if (current > gain) { idx = i; gain = current; } } return idx-1; } // Driver Code public static void Main() { int [] arr = { 2, 3, 1, 4, 0 }; Console.Write(bestIndex(arr)); } } // This code is contributed by sanjoy_62. |
Javascript
<script> // JavaScript code for the above approach // Function to find the rotation index k // that corresponds to the highest score function bestIndex(nums) { let N = nums.length; let gain = 0; let idx = 0; let q = []; for (let i = 0; i < N; i++) { let diff = i - nums[i]; if (diff >= 0) { gain++; q.push(diff); } } let current = gain; idx = 0; for (let i = 1; i <= N - 1; i++) { while (q.length == false && (i > (q[q.length - 1]))) { q.shift(); current--; } if (nums[i - 1] <= (N - 1)) { current++; q.push(i + (N - 1) - nums[i - 1]); } if (current > gain) { idx = i; gain = current; } } return idx-1; } // Driver Code let arr = [ 2, 3, 1, 4, 0 ]; document.write(bestIndex(arr)); // This code is contributed by code_hunt. </script> |
3
Time Complexity: O(N * logN)
Auxiliary Space: O(N)
Please Login to comment...