Rearrange and update array elements as specified by the given queries

Given an array arr[] of size N and queries Q[][], the task is to perform the following types of queries on the given array. 0: Left shift the array by one position.

  • 1: Right shift the array by one position.
  • 2 X Y: Update the value of arr[X] = Y.
  • 3 X: Print arr[X].

Example:

Input: arr[]={1, 2, 3, 4, 5}, Q[][]={{0}, {1}, {3, 1}, {2, 2, 54}, {3, 2}}.
Output:4 54
Explanation: 
Query1: The array arr[] modifies to {2, 3, 4, 5, 1} 
Query2: The array arr[] modifies to {1, 2, 3, 4, 5} 
Query3: Print the value of arr[1] i.e. 2 
Query4: The array arr[] modifies to {1, 54, 3, 4, 5} 
Query5: Print the value of arr[2], i.e. 54.

Input: arr[]={1}, Q[][]={{0}, {1}, {2, 0, 54}, {3, 0}}
Output: 54

Approach: The problem can be solved using Deque(Double Ended queue) to perform the insert and delete operation at the front and back of the queue in O(1). Follow the below steps to solve the problem.



  1. Create a double-ended Queue, dq.
  2. Push all elements of the array arr[] to dq.
  3. For the query of type 0(Left Shift), pop an element from the front of dq and push the element to the back of dq.
  4. For the query of type 1(Right Shift), pop an element from the back of dq and push the element to front of dq.
  5. For the query of type 2, update dq[X] = Y.
  6. For the query of type 3, print dq[X].

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to perform the
// given operations
void Queries(int arr[], int N,
             vector<vector<int> >& Q)
{
 
    // Dequeue to store the
    // array elements
    deque<int> dq;
 
    // Insert all element of
    // the array into the dequeue
    for (int i = 0; i < N; i++) {
        dq.push_back(arr[i]);
    }
 
    // Stores the size of the queue
    int sz = Q.size();
 
    // Traverse each query
    for (int i = 0; i < sz; i++) {
 
        // Query for left shift.
        if (Q[i][0] == 0) {
 
            // Extract the element at
            // the front of the queue
            int front = dq[0];
 
            // Pop the element at
            // the front of the queue
            dq.pop_front();
 
            // Push the element at
            // the back of the queue
            dq.push_back(front);
        }
 
        // Query for right shift
        else if (Q[i][0] == 1) {
 
            // Extract the element at
            // the back of the queue
            int back = dq[N - 1];
 
            // Pop the element at
            // the back of the queue
            dq.pop_back();
 
            // Push the element at
            // the front of the queue
            dq.push_front(back);
        }
 
        // Query for update
        else if (Q[i][0] == 2) {
 
            dq[Q[i][1]] = Q[i][2];
        }
 
        // Query to get the value
        else {
            cout << dq[Q[i][1]] << " ";
        }
    }
}
 
// Driver Code
int main()
{
 
    int arr[] = { 1, 2, 3, 4, 5 };
    int N = sizeof(arr) / sizeof(arr[0]);
    vector<vector<int> > Q;
 
    // All possible Queries
    Q = { { 0 }, { 1 }, { 3, 1 },
          { 2, 2, 54 }, { 3, 2 } };
 
    Queries(arr, N, Q);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.util.*;
class GFG{
 
// Function to perform the
// given operations
static void Queries(int arr[], int N,
                    int [][]Q)
{
  // Dequeue to store the
  // array elements
  Vector<Integer> dq = new Vector<>();
 
  // Insert all element of
  // the array into the dequeue
  for (int i = 0; i < N; i++)
  {
    dq.add(arr[i]);
  }
 
  // Stores the size of the queue
  int sz = Q.length;
 
  // Traverse each query
  for (int i = 0; i < sz; i++)
  {
    // Query for left shift.
    if (Q[i][0] == 0)
    {
      // Extract the element at
      // the front of the queue
      int front = dq.get(0);
 
      // Pop the element at
      // the front of the queue
      dq.remove(0);
 
      // Push the element at
      // the back of the queue
      dq.add(front);
    }
 
    // Query for right shift
    else if (Q[i][0] == 1)
    {
      // Extract the element at
      // the back of the queue
      int back = dq.elementAt(dq.size() - 1);
 
      // Pop the element at
      // the back of the queue
      dq.remove(dq.size() - 1);
 
      // Push the element at
      // the front of the queue
      dq.add(0, back);
    }
 
    // Query for update
    else if (Q[i][0] == 2)
    {
      dq.set(Q[i][1], Q[i][2]);
    }
 
    // Query to get the value
    else
    {
      System.out.print(dq.get(Q[i][1]) + " ");
    }
  }
}
 
// Driver Code
public static void main(String[] args)
{
  int arr[] = {1, 2, 3, 4, 5};
  int N = arr.length;
   
  // Vector<Vector<Integer>
  // > Q = new Vector<>();
 
  // All possible Queries
  int [][]Q = {{0}, {1}, {3, 1},
               {2, 2, 54}, {3, 2}};
  Queries(arr, N, Q);
}
}
 
// This code is contributed by Princi Singh

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
from collections import deque
 
# Function to perform the
# given operations
def Queries(arr, N, Q):
 
    # Dequeue to store the
    # array elements
    dq = deque()
 
    # Insert all element of
    # the array into the dequeue
    for i in range(N):
        dq.append(arr[i])
 
    # Stores the size of the queue
    sz = len(Q)
 
    # Traverse each query
    for i in range(sz):
 
        # Query for left shift.
        if (Q[i][0] == 0):
 
            # Extract the element at
            # the front of the queue
            front = dq[0]
 
            # Pop the element at
            # the front of the queue
            dq.popleft()
 
            # Push the element at
            # the back of the queue
            dq.appendleft(front)
 
        # Query for right shift
        elif (Q[i][0] == 1):
 
            # Extract the element at
            # the back of the queue
            back = dq[N - 1]
 
            # Pop the element at
            # the back of the queue
            dq.popleft()
 
            # Push the element at
            # the front of the queue
            dq.appendleft(back)
 
        # Query for update
        elif (Q[i][0] == 2):
            dq[Q[i][1]] = Q[i][2]
 
        # Query to get the value
        else:
            print(dq[Q[i][1]], end = " ")
 
# Driver Code
if __name__ == '__main__':
 
    arr = [ 1, 2, 3, 4, 5 ]
    N = len(arr)
 
    # All possible Queries
    Q = [ [ 0 ], [ 1 ], [ 3, 1 ],
          [ 2, 2, 54 ], [ 3, 2 ] ]
 
    Queries(arr, N, Q)
 
# This code is contributed by mohit kumar 29

chevron_right


Output: 

2 54


Time Complexity: O(N+|Q|)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.