Minimum rotations that have maximum elements with value at most its index
Last Updated :
12 Dec, 2022
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++
#include <bits/stdc++.h>
using namespace std;
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 ;
}
int calculate(vector< int >& arr)
{
int score = 0;
for ( int i = 0; i < arr.size(); i++) {
if (arr[i] <= i) {
score++;
}
}
return 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)
rotate(nums, N);
int cur_score = calculate(nums);
if (cur_score > high_score) {
min_idx = i;
high_score = cur_score;
}
}
return min_idx;
}
int main()
{
vector< int > arr = { 2, 3, 1, 4, 0 };
cout << bestIndex(arr);
return 0;
}
|
Java
import java.io.*;
public class GFG {
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 ;
}
static int calculate( int [] arr) {
int score = 0 ;
for ( int i = 0 ; i < arr.length; i++) {
if (arr[i] <= i) {
score++;
}
}
return 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 )
rotate(nums, N);
int cur_score = calculate(nums);
if (cur_score > high_score) {
min_idx = i;
high_score = cur_score;
}
}
return min_idx;
}
public static void main(String args[]) {
int [] arr = { 2 , 3 , 1 , 4 , 0 };
System.out.println(bestIndex(arr));
}
}
|
Python3
def rotate(arr, N):
temp = arr[ 0 ]
for i in range ( 0 , N - 1 ):
arr[i] = arr[i + 1 ]
arr[N - 1 ] = temp
return
def calculate(arr):
score = 0
for i in range ( 0 , len (arr)):
if (arr[i] < = i):
score = score + 1
return score
def bestIndex(nums):
N = len (nums)
high_score = - 1
min_idx = 0
for i in range ( 0 , N):
if (i ! = 0 ):
rotate(nums, N)
cur_score = calculate(nums)
if (cur_score > high_score):
min_idx = i
high_score = cur_score
return min_idx
arr = [ 2 , 3 , 1 , 4 , 0 ]
print (bestIndex(arr))
|
C#
using System;
class GFG
{
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 ;
}
static int calculate( int [] arr)
{
int score = 0;
for ( int i = 0; i < arr.Length; i++) {
if (arr[i] <= i) {
score++;
}
}
return 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)
rotate(nums, N);
int cur_score = calculate(nums);
if (cur_score > high_score) {
min_idx = i;
high_score = cur_score;
}
}
return min_idx;
}
public static void Main()
{
int [] arr = { 2, 3, 1, 4, 0 };
Console.Write(bestIndex(arr));
}
}
|
Javascript
<script>
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 calculate(arr) {
let score = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] <= i) {
score++;
}
}
return 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)
nums = [...rotate(nums, N)];
let cur_score = calculate(nums);
if (cur_score > high_score) {
min_idx = i;
high_score = cur_score;
}
}
return min_idx;
}
let arr = [2, 3, 1, 4, 0];
document.write(bestIndex(arr));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
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;
}
int main()
{
vector< int > arr = { 2, 3, 1, 4, 0 };
cout << bestIndex(arr);
return 0;
}
|
Java
import java.io.*;
public class GFG
{
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;
}
public static void main(String args[])
{
int [] arr = { 2 , 3 , 1 , 4 , 0 };
System.out.print(bestIndex(arr));
}
}
|
Python3
import array as arr
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
a = arr.array( 'b' , [ 2 , 3 , 1 , 4 , 0 ])
print (bestIndex(a))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
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;
}
public static void Main()
{
int [] arr = { 2, 3, 1, 4, 0 };
Console.Write(bestIndex(arr));
}
}
|
Javascript
<script>
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;
}
let arr = [ 2, 3, 1, 4, 0 ];
document.write(bestIndex(arr));
</script>
|
Time Complexity: O(N * logN)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...