Open In App

Array Queries

Last Updated : 11 Dec, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] and a list of queries q[], where each query specifies an operation to perform on the array, implement the class ArrayQueries that supports the following five methods:

  • Left: Perform one cyclic left rotation to the given array.
  • Right: Perform one cyclic right rotation to the given array.
  • Update (int pos, int val): Update the value of index pos by val.
  • Inc (int pos): Increment value at index pos by 1.
  • Pos (int pos): Return the current value at index pos.

Note: All the queries are performed based on 1-based indexing, although the array itself starts with index 0.

Examples:

Input: arr[] = [1, 2, 3], q[] = ["Left", "Inc 1", "Update 2 6", "Right", "Pos 1", "Pos 2", "Pos 3"]
Output: [1, 3, 6]
Explanation:
Left - Cyclic left rotation -> [2, 3, 1]
Inc 1 - Increment value at position 1 -> [3, 3, 1]
Update 2 6 -Set arr[2] = 6 -> [3, 6, 1]
Right - Cyclic right rotation -> [1, 3, 6]
Pos 1 -> 1
Pos 2 -> 3
Pos 3 -> 6

[Naive Approach] Direct Rotation by Shifting Elements

In the naive method, we physically perform every rotation on the array. For a Left operation, the first element is removed, all remaining elements are shifted one position to the left, and the removed element is placed at the end. For a Right operation, the last element is removed, all elements are shifted one position to the right, and the removed element is placed at the beginning. Since the array is always updated in its actual rotated form, the Update, Inc, and Pos operations are performed directly .

C++
#include <iostream>
#include<vector>
using namespace std;

class ArrayQueries {
  private:
    int *arr;
    int n;

  public:
    // Constructor: copies the input array
    ArrayQueries(int arr[], int n) {
        this->n = n;
        this->arr = new int[n];
        for (int i = 0; i < n; i++) {
            this->arr[i] = arr[i];
        }
    }

    // Performs one cyclic left rotation:
    void Left() {
        if (n == 0) return;

        int first = arr[0];             
        for (int i = 1; i < n; i++) {
            arr[i - 1] = arr[i];        
        }
        arr[n - 1] = first;              
    }

    // Performs one cyclic right rotation:
    void Right() {
        if (n == 0) return;

        int last = arr[n - 1];           
        for (int i = n - 2; i >= 0; i--) {
            arr[i + 1] = arr[i];         
        }
        arr[0] = last;                  
    }

    // Updates the value at 1-based index pos
    void Update(int pos, int val) {
        arr[pos - 1] = val;             
    }

    // Increments the value at 1-based index pos by 1
    void Inc(int pos) {
        arr[pos - 1]++;                  
    }

    // Returns the value at 1-based index pos
    int Pos(int pos) {
        return arr[pos - 1];           
    }
};

int main() {
   
    int N = 3;
    int arr[] = {1, 2, 3};

    ArrayQueries aq(arr, N);

    int Q = 7;
    aq.Left();         
    aq.Inc(1);          
    aq.Update(2, 6);   
    aq.Right();         

    cout << aq.Pos(1) << " " << aq.Pos(2) << " " << aq.Pos(3);
    return 0;
}
Java
import java.util.Arrays;

class ArrayQueries{
    private int[] arr;
    private int n;

    // Constructor: copies the input array
    ArrayQueries(int[] arr, int n) {
        this.n = n;
        this.arr = new int[n];
        for (int i = 0; i < n; i++) {
            this.arr[i] = arr[i];
        }
    }

    // Performs one cyclic left rotation
    void Left() {
        if (n == 0) return;

        int first = arr[0];            
        for (int i = 1; i < n; i++) {
            arr[i - 1] = arr[i];        
        }
        arr[n - 1] = first;             
    }

    // Performs one cyclic right rotation
    void Right() {
        if (n == 0) return;

        int last = arr[n - 1];            
        for (int i = n - 2; i >= 0; i--) {
            arr[i + 1] = arr[i];         
        }
        arr[0] = last;                 
    }

    // Updates the value at 1-based index pos
    void Update(int pos, int val) {
        arr[pos - 1] = val;
    }

    // Increments the value at 1-based index pos by 1
    void Inc(int pos) {
        arr[pos - 1]++;
    }

    // Returns the value at 1-based index pos
    int Pos(int pos) {
        return arr[pos - 1];
    }
}

public class Main {
    public static void main(String[] args) {
        int N = 3;
        int[] arr = {1, 2, 3};

        ArrayQueries aq = new ArrayQueries(arr, N);

        int Q = 7;
        aq.Left();        
        aq.Inc(1);       
        aq.Update(2, 6);  
        aq.Right();       

        System.out.println(aq.Pos(1) + " " + aq.Pos(2) + " " + aq.Pos(3));    
    }
}
Python
class ArrayQueries:
    # Constructor: copies the input array
    def __init__(self, arr, n):
        self.n = n
        self.arr = arr[:]

    # Performs one cyclic left rotation:
    def Left(self):
        if self.n == 0:
            return
        first = self.arr[0]              
        for i in range(1, self.n):
            self.arr[i - 1] = self.arr[i]         
        self.arr[self.n - 1] = first              

    # Performs one cyclic right rotation:
    def Right(self):
        if self.n == 0:
            return
        last = self.arr[self.n - 1]           
        for i in range(self.n - 2, -1, -1):
            self.arr[i + 1] = self.arr[i]         
        self.arr[0] = last                  

    # Updates the value at 1-based index pos
    def Update(self, pos, val):
        self.arr[pos - 1] = val             

    # Increments the value at 1-based index pos by 1
    def Inc(self, pos):
        self.arr[pos - 1] += 1                  

    # Returns the value at 1-based index pos
    def Pos(self, pos):
        return self.arr[pos - 1]           


if __name__ == "__main__":
    N = 3
    arr = [1, 2, 3]

    aq = ArrayQueries(arr, N)

    Q = 7
    aq.Left()         
    aq.Inc(1)          
    aq.Update(2, 6)   
    aq.Right()         

    print(aq.Pos(1), aq.Pos(2), aq.Pos(3))
C#
using System;

class ArrayQueries {
    private int[] arr;
    private int n;

    // Constructor: copies the input array
    public ArrayQueries(int[] arr, int n) {
        this.n = n;
        this.arr = new int[n];
        for (int i = 0; i < n; i++) {
            this.arr[i] = arr[i];
        }
    }

    // Performs one cyclic left rotation:
    public void Left() {
        if (n == 0) return;

        int first = arr[0];              
        for (int i = 1; i < n; i++) {
            arr[i - 1] = arr[i];         
        }
        arr[n - 1] = first;              
    }

    // Performs one cyclic right rotation:
    public void Right() {
        if (n == 0) return;

        int last = arr[n - 1];           
        for (int i = n - 2; i >= 0; i--) {
            arr[i + 1] = arr[i];         
        }
        arr[0] = last;                  
    }

    // Updates the value at 1-based index pos
    public void Update(int pos, int val) {
        arr[pos - 1] = val;             
    }

    // Increments the value at 1-based index pos by 1
    public void Inc(int pos) {
        arr[pos - 1]++;                  
    }

    // Returns the value at 1-based index pos
    public int Pos(int pos) {
        return arr[pos - 1];           
    }
}

class GFG {
    static void Main() {
        int N = 3;
        int[] arr = {1, 2, 3};

        ArrayQueries aq = new ArrayQueries(arr, N);

        aq.Left();         
        aq.Inc(1);          
        aq.Update(2, 6);   
        aq.Right();         

        Console.WriteLine(aq.Pos(1) + " " + aq.Pos(2) + " " + aq.Pos(3));
    }
}
JavaScript
class ArrayQueries {
    // Constructor: copies the input array
    constructor(arr, n) {
        this.n = n;
        this.arr = new Array(n);
        for (let i = 0; i < n; i++) {
            this.arr[i] = arr[i];
        }
    }

    // Performs one cyclic left rotation:
    Left() {
        if (this.n === 0) return;

        const first = this.arr[0];              
        for (let i = 1; i < this.n; i++) {
            this.arr[i - 1] = this.arr[i];         
        }
        this.arr[this.n - 1] = first;              
    }

    // Performs one cyclic right rotation:
    Right() {
        if (this.n === 0) return;

        const last = this.arr[this.n - 1];           
        for (let i = this.n - 2; i >= 0; i--) {
            this.arr[i + 1] = this.arr[i];         
        }
        this.arr[0] = last;                  
    }

    // Updates the value at 1-based index pos
    Update(pos, val) {
        this.arr[pos - 1] = val;             
    }

    // Increments the value at 1-based index pos by 1
    Inc(pos) {
        this.arr[pos - 1]++;                  
    }

    // Returns the value at 1-based index pos
    Pos(pos) {
        return this.arr[pos - 1];           
    }
}

//Driver Code
const N = 3;
const arr = [1, 2, 3];

const aq = new ArrayQueries(arr, N);

const Q = 7;
aq.Left();         
aq.Inc(1);          
aq.Update(2, 6);   
aq.Right();         

console.log(aq.Pos(1) + " " + aq.Pos(2) + " " + aq.Pos(3));

Output
1 3 6

Time Complexity

  • Left -> O(n)
  • Right -> O(n)
  • Update -> O(1)
  • Inc -> O(1)
  • Pos -> O(1)

Space Complexity: O(n)

[Efficient Approach] Offset-Based Circular Array

In the optimized method, we avoid physically rotating the array. Instead, we maintain a single integer called an offset that represents the net effect of all rotations. The array remains unchanged in memory. When a Left operation is performed, the offset is updated accordingly, and when a Right operation is performed, the offset is updated in the opposite direction, both modulo N. For any query involving a position pos, the actual index in the original array is computed using the offset. After this index mapping, the Update, Inc, and Pos operations become simple direct array accesses.

C++
#include <iostream>
#include<vector>
using namespace std;

class ArrayQueries {
  private:
    int *arr;     
    int n;       
    int shift = 0; 

  public:
    // Constructor: copies the input array
    ArrayQueries(int arr[], int n) {
        this->n = n;
        this->arr = new int[n];
        for (int i = 0; i < n; i++) {
            this->arr[i] = arr[i];
        }
    }

    // Performs one cyclic left rotation:
    // Instead of shifting elements, we only update shift
    void Left() {
        shift = (shift - 1 + n) % n;
    }

    // Performs one cyclic right rotation:
    // We again only update shift
    void Right() {
        shift = (shift + 1) % n;
    }

    // Updates the value at 1-based index pos
    // We first convert the logical position to the actual index
    void Update(int pos, int val) {
        int idx = (pos - 1 - shift + n) % n;
        arr[idx] = val;             
    }

    // Increments the value at 1-based index pos by 1
    // Logical index is mapped to physical index using shift
    void Inc(int pos) {
        int idx = (pos - 1 - shift + n) % n;
        arr[idx]++;                  
    }

    // Returns the value at 1-based index pos
    // Logical index is converted to the real array index
    int Pos(int pos) {
        int idx = (pos - 1 - shift + n) % n;
        return arr[idx];           
    }
};

int main() {
   
    int N = 3;
    int arr[] = {1, 2, 3};

    ArrayQueries aq(arr, N);

    int Q = 7;
    aq.Left();         
    aq.Inc(1);          
    aq.Update(2, 6);   
    aq.Right();         

    cout << aq.Pos(1) << " " << aq.Pos(2) << " " << aq.Pos(3);

    return 0;
}
Java
import java.util.Arrays;

class ArrayQueries {
    private int[] arr;     
    private int n;       
    private int shift = 0; 

    // Constructor: copies the input array
    ArrayQueries(int arr[], int n) {
        this.n = n;
        this.arr = new int[n];
        for (int i = 0; i < n; i++) {
            this.arr[i] = arr[i];
        }
    }

    // Performs one cyclic left rotation:
    // Instead of shifting elements, we only update shift
    void Left() {
        shift = (shift - 1 + n) % n;
    }

    // Performs one cyclic right rotation:
    // We again only update shift
    void Right() {
        shift = (shift + 1) % n;
    }

    // Updates the value at 1-based index pos
    // We first convert the logical position to the actual index
    void Update(int pos, int val) {
        int idx = (pos - 1 - shift + n) % n;
        arr[idx] = val;             
    }

    // Increments the value at 1-based index pos by 1
    // Logical index is mapped to physical index using shift
    void Inc(int pos) {
        int idx = (pos - 1 - shift + n) % n;
        arr[idx]++;                  
    }

    // Returns the value at 1-based index pos
    // Logical index is converted to the real array index
    int Pos(int pos) {
        int idx = (pos - 1 - shift + n) % n;
        return arr[idx];           
    }
}

public class GFG {
    public static void main(String[] args) {
        int N = 3;
        int[] arr = {1, 2, 3};

        ArrayQueries aq = new ArrayQueries(arr, N);

        int Q = 7;
        aq.Left();         
        aq.Inc(1);          
        aq.Update(2, 6);   
        aq.Right();         

        System.out.print(aq.Pos(1) + " " + aq.Pos(2) + " " + aq.Pos(3));
    }
}
Python
class ArrayQueries:
    def __init__(self, arr, n):
        self.arr = arr[:]
        self.n = n
        self.shift = 0

    # Performs one cyclic left rotation:
    # Instead of shifting elements, we only update shift
    def Left(self):
        self.shift = (self.shift - 1 + self.n) % self.n

    # Performs one cyclic right rotation:
    # We again only update shift
    def Right(self):
        self.shift = (self.shift + 1) % self.n

    # Updates the value at 1-based index pos
    # We first convert the logical position to the actual index
    def Update(self, pos, val):
        idx = (pos - 1 - self.shift + self.n) % self.n
        self.arr[idx] = val             

    # Increments the value at 1-based index pos by 1
    def Inc(self, pos):
        idx = (pos - 1 - self.shift + self.n) % self.n
        self.arr[idx] += 1                  

    # Returns the value at 1-based index pos
    def Pos(self, pos):
        idx = (pos - 1 - self.shift + self.n) % self.n
        return self.arr[idx]           


if __name__ == "__main__":
    N = 3
    arr = [1, 2, 3]

    aq = ArrayQueries(arr, N)

    Q = 7
    aq.Left()         
    aq.Inc(1)          
    aq.Update(2, 6)   
    aq.Right()         

    print(aq.Pos(1), aq.Pos(2), aq.Pos(3))
C#
using System;

class ArrayQueries {
    private int[] arr;     
    private int n;       
    private int shift = 0; 

    // Constructor: copies the input array
    public ArrayQueries(int[] arr, int n) {
        this.n = n;
        this.arr = new int[n];
        for (int i = 0; i < n; i++) {
            this.arr[i] = arr[i];
        }
    }

    // Performs one cyclic left rotation:
    // Instead of shifting elements, we only update shift
    public void Left() {
        shift = (shift - 1 + n) % n;
    }

    // Performs one cyclic right rotation:
    // We again only update shift
    public void Right() {
        shift = (shift + 1) % n;
    }

    // Updates the value at 1-based index pos
    // We first convert the logical position to the actual index
    public void Update(int pos, int val) {
        int idx = (pos - 1 - shift + n) % n;
        arr[idx] = val;             
    }

    // Increments the value at 1-based index pos by 1
    // Logical index is mapped to physical index using shift
    public void Inc(int pos) {
        int idx = (pos - 1 - shift + n) % n;
        arr[idx]++;                  
    }

    // Returns the value at 1-based index pos
    // Logical index is converted to the real array index
    public int Pos(int pos) {
        int idx = (pos - 1 - shift + n) % n;
        return arr[idx];           
    }
}

class GFG {
    static void Main() {
        int N = 3;
        int[] arr = {1, 2, 3};

        ArrayQueries aq = new ArrayQueries(arr, N);

        aq.Left();         
        aq.Inc(1);          
        aq.Update(2, 6);   
        aq.Right();         

        Console.WriteLine(aq.Pos(1) + " " + aq.Pos(2) + " " + aq.Pos(3));
    }
}
JavaScript
class ArrayQueries {
    constructor(arr, n) {
        this.arr = new Array(n);
        this.n = n;
        this.shift = 0;

        // Constructor: copies the input array
        for (let i = 0; i < n; i++) {
            this.arr[i] = arr[i];
        }
    }

    // Performs one cyclic left rotation:
    // Instead of shifting elements, we only update shift
    Left() {
        this.shift = (this.shift - 1 + this.n) % this.n;
    }

    // Performs one cyclic right rotation:
    // We again only update shift
    Right() {
        this.shift = (this.shift + 1) % this.n;
    }

    // Updates the value at 1-based index pos
    // We first convert the logical position to the actual index
    Update(pos, val) {
        const idx = (pos - 1 - this.shift + this.n) % this.n;
        this.arr[idx] = val;             
    }

    // Increments the value at 1-based index pos by 1
    // Logical index is mapped to physical index using shift
    Inc(pos) {
        const idx = (pos - 1 - this.shift + this.n) % this.n;
        this.arr[idx]++;                  
    }

    // Returns the value at 1-based index pos
    // Logical index is converted to the real array index
    Pos(pos) {
        const idx = (pos - 1 - this.shift + this.n) % this.n;
        return this.arr[idx];           
    }
}

//Driver Code
const N = 3;
const arr = [1, 2, 3];

const aq = new ArrayQueries(arr, N);

const Q = 7;
aq.Left();         
aq.Inc(1);          
aq.Update(2, 6);   
aq.Right();         

console.log(aq.Pos(1) + " " + aq.Pos(2) + " " + aq.Pos(3));

Output
1 3 6

Time Complexity

  • Left -> O(1)
  • Right -> O(1)
  • Update -> O(1)
  • Inc -> O(1)
  • Pos -> O(1)

Space Complexity: O(n)


Article Tags :

Explore