Find element at given index after a number of rotations
Given an array of N integers, M ranges of indices as queries, and a specific index K, the task is to right rotate the array circularly between query ranges, and return the element at Kth index in the final array.
Examples:
Input: arr[] : {1, 2, 3, 4, 5}, M = 2, queries[] = { {0, 2}, {0, 3} }, K = 1
Output: 3
Explanation: After rotation according to 1st query {0, 2} = arr[] = {3, 1, 2, 4, 5}
After rotation according to 2nd query {0, 3} = arr[] = {4, 3, 1, 2, 5}
Now after M rotations, the element at Kth index = arr[1] = 3Input: arr[] : {1, 2, 3, 4, 5}, M = 2, queries[] = { {0, 3}, {3, 4} }, K = 1
Output: 1
Explanation: After rotation according to 1st query {0, 3} = arr[] = {4, 1, 2, 3, 5}
After rotation according to 2nd query {3, 4} = arr[] = {4, 1, 2, 5, 3}
Now after M rotations, the element at Kth index = arr[1] = 1
Naive Approach:
The brute approach is to actually rotate the array for all given ranges, and finally, return the element at the given index in the modified array.
C++
#include <bits/stdc++.h> using namespace std; int findElement(vector< int > arr, int ranges[][2], int rotations, int index) { // Track of the rotation number int n1 = 1; // Track of the row index for the ranges[][] array int i = 0; // Initialize the left side of the ranges[][] array int leftRange = 0; // Initialize the right side of the ranges[][] array int rightRange = 0; // Initialize the key variable int key = 0; while (n1 <= rotations) { leftRange = ranges[i][0]; rightRange = ranges[i][1]; key = arr[rightRange]; for ( int j = rightRange; j >= leftRange + 1; j--) { arr[j] = arr[j - 1]; } arr[leftRange] = key; n1++; i++; } // Return the element after all the rotations return arr[index]; } int main() { vector< int > arr{ 1, 2, 3, 4, 5 }; // No. of rotations int rotations = 2; // Ranges according to 0-based indexing int ranges[][2] = { { 0, 2 }, { 0, 3 } }; int index = 1; cout << (findElement(arr, ranges, rotations, index)); } // This code is contributed by garg28harsh. |
Java
// Brute Force Method // Java Program to find the element at given index after a // number of rotations public class Main { public static int findElement( int [] arr, int [][] ranges, int rotations, int index) { // Track of the rotation number int n1 = 1 ; // Track of the row index for the ranges[][] array int i = 0 ; // Initialize the left side of the ranges[][] array int leftRange = 0 ; // Initialize the right side of the ranges[][] array int rightRange = 0 ; // Initialize the key variable int key = 0 ; while (n1 <= rotations) { leftRange = ranges[i][ 0 ]; rightRange = ranges[i][ 1 ]; key = arr[rightRange]; for ( int j = rightRange; j >= leftRange + 1 ; j--) { arr[j] = arr[j - 1 ]; } arr[leftRange] = key; n1++; i++; } // Return the element after all the rotations return arr[index]; } public static void main(String[] args) { int [] arr = { 1 , 2 , 3 , 4 , 5 }; // No. of rotations int rotations = 2 ; // Ranges according to 0-based indexing int [][] ranges = { { 0 , 2 }, { 0 , 3 } }; int index = 1 ; System.out.println( findElement(arr, ranges, rotations, index)); ; } } // This code is contributed by Sagar Srikant |
Python3
# Python code for above approach import array as arr def findElement(arr, ranges, rotations, index): # Track of the rotation number n1 = 1 # Track of the row index for the ranges[][] array i = 0 # Initialize the left side of the ranges[][] array leftRange = 0 # Initialize the right side of the ranges[][] array rightRange = 0 # Initialize the key variable key = 0 while (n1 < = rotations): leftRange = ranges[i][ 0 ] rightRange = ranges[i][ 1 ] key = arr[rightRange] j = rightRange while (j < = rightRange & j > leftRange): arr[j] = arr[j - 1 ] j = j - 1 arr[leftRange] = key n1 = n1 + 1 i = i + 1 # Return the element after all the rotations return arr[index] # driver code ar = arr.array( 'i' , [ 1 , 2 , 3 , 4 , 5 ]) # No. of rotations rotations = 2 # Ranges according to 0-based indexing ranges = [[ 0 , 2 ], [ 0 , 3 ]] index = 1 print (findElement(ar, ranges, rotations, index)) # This code is contributed by adityamaharshi21. |
C#
// Include namespace system using System; // Brute Force Method // C# Program to find the element at given index after a // number of rotations class GFG { static int findElement( int [] arr, int [,] ranges, int rotations, int index) { // Track of the rotation number var n1 = 1; // Track of the row index for the ranges[][] array var i = 0; // Initialize the left side of the ranges[][] array var leftRange = 0; // Initialize the right side of the ranges[][] array var rightRange = 0; // Initialize the key variable var key = 0; while (n1 <= rotations) { leftRange = ranges[i,0]; rightRange = ranges[i,1]; key = arr[rightRange]; for ( int j = rightRange; j >= leftRange + 1; j--) { arr[j] = arr[j - 1]; } arr[leftRange] = key; n1++; i++; } // Return the element after all the rotations return arr[index]; } public static void Main() { int [] arr = {1, 2, 3, 4, 5}; // No. of rotations var rotations = 2; // Ranges according to 0-based indexing int [,] ranges = {{0, 2}, {0, 3}}; var index = 1; Console.WriteLine(GFG.findElement(arr, ranges, rotations, index)); ; } } |
Javascript
function findElement(arr, ranges, rotations, index) { // Track of the rotation number let n1 = 1; // Track of the row index for the ranges[][] array let i = 0; // Initialize the left side of the ranges[][] array let leftRange = 0; // Initialize the right side of the ranges[][] array let rightRange = 0; // Initialize the key variable let key = 0; while (n1 <= rotations) { leftRange = ranges[i][0]; rightRange = ranges[i][1]; key = arr[rightRange]; for (let j = rightRange; j >= leftRange + 1; j--) { arr[j] = arr[j - 1]; } arr[leftRange] = key; n1++; i++; } // Return the element after all the rotations return arr[index]; } let arr=[ 1, 2, 3, 4, 5 ]; // No. of rotations let rotations = 2; // Ranges according to 0-based indexing var ranges = new Array(2); for ( var i = 0; i < ranges.length; i++) { ranges[i] = new Array(2); } ranges[0][0] = 0,ranges[0][1]=2; ranges[1][0] = 0,ranges[1][1]=3; let index = 1; console.log(findElement(arr, ranges, rotations, index)); // This code is contributed by garg28harsh. |
3
Time Complexity: O(N * Q)
Auxiliary Space: O(1), since no extra space has been taken.
Efficient Approach:
The idea is to calculate the relative position of the index each time the rotation is performed. We can do this simply by checking for the range in which the rotation is to be performed and updating the value of the index according to that. But we need to perform the rotation in a reverse manner.
The reason for doing so can be justified as follows:
- It may be possible that we are rotating some overlapped positions repeatedly.
- In those cases, we are going deeper into the previous rotations starting from the latest rotation.
- So to get the proper position we are iterating from the reverse direction.
Please note that we are not rotating the elements in the reverse order, just processing the index from the reverse. Because if we actually rotate in reverse order, we might get a completely different answer as in the case of rotations the order matters.
Follow along with the below illustration for a better understanding.
Illustration:
Let the given array be arr[] = {10, 20, 30, 40, 50 }
query: {{0, 2} {0, 3}}, K = 1.We will consider the rotations from the backside.
query 2 {0, 3}:
=> index = 1 and index ≥ 0 and index ≤ 3
=> index ≠ left therefore, index = 0query 1 {0, 2}:
=> index = 0 and index >= 0 and index <= 2
=> index = left therefore, index = 2Therefore we return arr[index] =arr[2] = 30
Follow the below steps to implement the idea:
- Iterate the queries from reverse direction:
- If the range contains the value K, then update its position before rotation.
- Continue the above two steps till all the queries are traversed.
- Return the value at the index K (K updated through all the queries)
Below is the implementation of the above approach:
C++
// CPP code to rotate an array // and answer the index query #include <bits/stdc++.h> using namespace std; // Function to compute the element at // given index int findElement( int arr[], int ranges[][2], int rotations, int index) { for ( int i = rotations - 1; i >= 0; i--) { // Range[left...right] int left = ranges[i][0]; int right = ranges[i][1]; // Rotation will not have any effect if (left <= index && right >= index) { if (index == left) index = right; else index--; } } // Returning new element return arr[index]; } // Driver int main() { int arr[] = { 1, 2, 3, 4, 5 }; // No. of rotations int rotations = 2; // Ranges according to 0-based indexing int ranges[rotations][2] = { { 0, 2 }, { 0, 3 } }; int index = 1; cout << findElement(arr, ranges, rotations, index); return 0; } |
C
// C code to rotate an array // and answer the index query #include <stdio.h> // Function to compute the element at // given index int findElement( int arr[], int ranges[][2], int rotations, int index) { for ( int i = rotations - 1; i >= 0; i--) { // Range[left...right] int left = ranges[i][0]; int right = ranges[i][1]; // Rotation will not have any effect if (left <= index && right >= index) { if (index == left) index = right; else index--; } } // Returning new element return arr[index]; } // Driver int main() { int arr[] = { 1, 2, 3, 4, 5 }; // No. of rotations int rotations = 2; // Ranges according to 0-based indexing int ranges[2][2] = { { 0, 2 }, { 0, 3 } }; int index = 1; printf ( "%d" , findElement(arr, ranges, rotations, index)); return 0; } // This code is contributed by Deepthi |
Java
// Java code to rotate an array // and answer the index query import java.util.*; class GFG { // Function to compute the element at // given index static int findElement( int [] arr, int [][] ranges, int rotations, int index) { for ( int i = rotations - 1 ; i >= 0 ; i--) { // Range[left...right] int left = ranges[i][ 0 ]; int right = ranges[i][ 1 ]; // Rotation will not have any effect if (left <= index && right >= index) { if (index == left) index = right; else index--; } } // Returning new element return arr[index]; } // Driver public static void main(String[] args) { int [] arr = { 1 , 2 , 3 , 4 , 5 }; // No. of rotations int rotations = 2 ; // Ranges according to 0-based indexing int [][] ranges = { { 0 , 2 }, { 0 , 3 } }; int index = 1 ; System.out.println(findElement(arr, ranges, rotations, index)); } } /* This code is contributed by Mr. Somesh Awasthi */ |
Python3
# Python 3 code to rotate an array # and answer the index query # Function to compute the element # at given index def findElement(arr, ranges, rotations, index) : for i in range (rotations - 1 , - 1 , - 1 ) : # Range[left...right] left = ranges[i][ 0 ] right = ranges[i][ 1 ] # Rotation will not have # any effect if (left < = index and right > = index) : if (index = = left) : index = right else : index = index - 1 # Returning new element return arr[index] # Driver Code arr = [ 1 , 2 , 3 , 4 , 5 ] # No. of rotations rotations = 2 # Ranges according to # 0-based indexing ranges = [ [ 0 , 2 ], [ 0 , 3 ] ] index = 1 print (findElement(arr, ranges, rotations, index)) # This code is contributed by Nikita Tiwari. |
C#
// C# code to rotate an array // and answer the index query using System; class GFG { // Function to compute the // element at given index static int findElement( int [] arr, int [, ] ranges, int rotations, int index) { for ( int i = rotations - 1; i >= 0; i--) { // Range[left...right] int left = ranges[i, 0]; int right = ranges[i, 1]; // Rotation will not // have any effect if (left <= index && right >= index) { if (index == left) index = right; else index--; } } // Returning new element return arr[index]; } // Driver Code public static void Main() { int [] arr = { 1, 2, 3, 4, 5 }; // No. of rotations int rotations = 2; // Ranges according // to 0-based indexing int [, ] ranges = { { 0, 2 }, { 0, 3 } }; int index = 1; Console.Write(findElement(arr, ranges, rotations, index)); } } // This code is contributed // by nitin mittal. |
PHP
<?php // PHP code to rotate an array // and answer the index query // Function to compute the // element at given index function findElement( $arr , $ranges , $rotations , $index ) { for ( $i = $rotations - 1; $i >= 0; $i --) { // Range[left...right] $left = $ranges [ $i ][0]; $right = $ranges [ $i ][1]; // Rotation will not // have any effect if ( $left <= $index && $right >= $index ) { if ( $index == $left ) $index = $right ; else $index --; } } // Returning new element return $arr [ $index ]; } // Driver Code $arr = array (1, 2, 3, 4, 5); // No. of rotations $rotations = 2; // Ranges according // to 0-based indexing $ranges = array ( array (0, 2), array (0, 3)); $index = 1; echo findElement( $arr , $ranges , $rotations , $index ); // This code is contributed by ajit ?> |
Javascript
<script> // JavaScript code to rotate an array // and answer the index query // Function to compute the element at // given index let findElement = (arr, ranges, rotations, index)=>{ for (let i = rotations - 1; i >= 0; i--) { // Range[left...right] let left = ranges[i][0]; let right = ranges[i][1]; // Rotation will not have any effect if (left <= index && right >= index) { if (index == left) index = right; else index--; } } // Returning new element return arr[index]; } // Driver Code let arr = [ 1, 2, 3, 4, 5 ]; // No. of rotations let rotations = 2; // Ranges according to 0-based indexing let ranges = [ [ 0, 2 ], [ 0, 3] ]; let index = 1; document.write(findElement(arr, ranges, rotations, index)); </script> |
3
Time Complexity: O(R), R is the number of rotations.
Auxiliary Space: O(1)
This article is contributed by Rohit Thapliyal. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above.
Please Login to comment...