Open In App

Find element at given index after a number of rotations

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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] = 3

Input: 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++





Java





Python3





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.


Output

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 = 0

query 1 {0, 2}:
        => index = 0 and index >= 0 and index <= 2
        => index = left therefore, index = 2

Therefore 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>


Output

3

Time Complexity: O(R), R is the number of rotations.
Auxiliary Space: O(1)



Last Updated : 19 Sep, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads