Elements Shifting

Last Updated : 14 Jul, 2026

Geek starts with an array of length 2n - 1 indexed from 1 to 2n - 1. Initially, for every i (1 â‰Ī i â‰Ī n), the value i is placed at index 2i - 1, and all other positions are empty. Geek repeatedly performs the following operation:

  • Select the non-empty cell with the largest index.
  • Move its value to the nearest empty cell on its left.

He continues performing this operation until the first n positions of the array become completely filled. The figure below illustrates the process for n = 4. 

2056958479

Given an array queries[] containing q indices, return the elements present at those indices in the final array after all operations are completed.

Examples:

Input: n = 4, queries[] = [2, 3, 4]
Output: [3, 2, 4]
Explanation: After performing all operations, the final array becomes: [1, 3, 2, 4]. Therefore, the elements at indices 2, 3, and 4 are 3, 2, and 4 respectively.

Input: n = 13, queries[] = [10, 5, 4, 8]
Output: [13, 3, 8, 9]
Explanation: After performing all operations, the final array becomes: [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7]. Therefore, the elements at indices 10, 5, 4, and 8 are 13, 3, 8, and 9 respectively.

[Naive Approach] Array Simulation - O(nÂē) Time and O(n) Space

Place numbers 1 to n at odd positions. Repeatedly shift rightmost occupied element to nearest empty cell on its left until first n cells are filled. Return values at query positions.

  • Create array of size 2n initialized to 0
  • Place i at position 2i-1 for i from 1 to n
  • While first n cells not all filled
  • Find rightmost occupied cell
  • Find nearest empty cell to its left
  • Move occupied value to empty cell
  • Answer queries from array
C++
#include <bits/stdc++.h>
using namespace std;

vector<int> findElements(int n, vector<int>& queries) {

    vector<int> arr(2 * n, 0);

    // Initially place elements at odd indices (1-based indexing)
    for (int i = 1; i <= n; i++)
        arr[2 * i - 1] = i;

    // Simulate the shifting process
    while (true) {

        bool complete = true;
        for (int i = 1; i <= n; i++) {
            if (arr[i] == 0) {
                complete = false;
                break;
            }
        }

        if (complete)
            break;

        // Find the rightmost occupied cell
        int occupied = -1;
        for (int i = 2 * n - 1; i >= 1; i--) {
            if (arr[i] != 0) {
                occupied = i;
                break;
            }
        }

        // Find nearest empty cell on its left
        int empty = occupied - 1;
        while (empty >= 1 && arr[empty] != 0)
            empty--;

        arr[empty] = arr[occupied];
        arr[occupied] = 0;
    }

    vector<int> ans;

    for (int idx : queries)
        ans.push_back(arr[idx]);

    return ans;
}

int main() {

    int n = 4;
    vector<int> queries = {2, 3, 4};

    vector<int> ans = findElements(n, queries);

    for (int x : ans)
        cout << x << " ";

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

class GFG {
    
    public static ArrayList<Integer> findElements(int n, int[] queries) {
        int[] arr = new int[2 * n];
        
        // Initially place elements at odd indices (1-based indexing)
        for (int i = 1; i <= n; i++) {
            arr[2 * i - 1] = i;
        }
        
        // Simulate the shifting process
        while (true) {
            boolean complete = true;
            for (int i = 1; i <= n; i++) {
                if (arr[i] == 0) {
                    complete = false;
                    break;
                }
            }
            
            if (complete)
                break;
            
            // Find the rightmost occupied cell
            int occupied = -1;
            for (int i = 2 * n - 1; i >= 1; i--) {
                if (arr[i] != 0) {
                    occupied = i;
                    break;
                }
            }
            
            // Find nearest empty cell on its left
            int empty = occupied - 1;
            while (empty >= 1 && arr[empty] != 0) {
                empty--;
            }
            
            arr[empty] = arr[occupied];
            arr[occupied] = 0;
        }
        
        ArrayList<Integer> ans = new ArrayList<>();
        
        for (int idx : queries) {
            ans.add(arr[idx]);
        }
        
        return ans;
    }
    
    public static void main(String[] args) {
        int n = 4;
        int[] queries = {2, 3, 4};
        
        ArrayList<Integer> ans = findElements(n, queries);
        
        for (int x : ans) {
            System.out.print(x + " ");
        }
    }
}
Python
def findElements(n, queries):
    arr = [0] * (2 * n)
    
    # Initially place elements at odd indices (1-based indexing)
    for i in range(1, n + 1):
        arr[2 * i - 1] = i
    
    # Simulate the shifting process
    while True:
        complete = True
        for i in range(1, n + 1):
            if arr[i] == 0:
                complete = False
                break
        
        if complete:
            break
        
        # Find the rightmost occupied cell
        occupied = -1
        for i in range(2 * n - 1, 0, -1):
            if arr[i] != 0:
                occupied = i
                break
        
        # Find nearest empty cell on its left
        empty = occupied - 1
        while empty >= 1 and arr[empty] != 0:
            empty -= 1
        
        arr[empty] = arr[occupied]
        arr[occupied] = 0
    
    ans = []
    for idx in queries:
        ans.append(arr[idx])
    
    return ans

if __name__ == "__main__":
    n = 4
    queries = [2, 3, 4]
    
    ans = findElements(n, queries)
    
    print(' '.join(map(str, ans)))
C#
using System;
using System.Collections.Generic;

class GfG {
    
    public  static List<int> findElements(int n, int[] queries) {
        int[] arr = new int[2 * n];
        
        // Initially place elements at odd indices (1-based indexing)
        for (int i = 1; i <= n; i++) {
            arr[2 * i - 1] = i;
        }
        
        // Simulate the shifting process
        while (true) {
            bool complete = true;
            for (int i = 1; i <= n; i++) {
                if (arr[i] == 0) {
                    complete = false;
                    break;
                }
            }
            
            if (complete)
                break;
            
            // Find the rightmost occupied cell
            int occupied = -1;
            for (int i = 2 * n - 1; i >= 1; i--) {
                if (arr[i] != 0) {
                    occupied = i;
                    break;
                }
            }
            
            // Find nearest empty cell on its left
            int empty = occupied - 1;
            while (empty >= 1 && arr[empty] != 0) {
                empty--;
            }
            
            arr[empty] = arr[occupied];
            arr[occupied] = 0;
        }
        
        List<int> ans = new List<int>();
        
        foreach (int idx in queries) {
            ans.Add(arr[idx]);
        }
        
        return ans;
    }
    
    static void Main(string[] args) {
        int n = 4;
        int[] queries = {2, 3, 4};
        
        List<int> ans = findElements(n, queries);
        
        foreach (int x in ans) {
            Console.Write(x + " ");
        }
    }
}
JavaScript
function findElements(n, queries) {
    let arr = new Array(2 * n).fill(0);
    
    // Initially place elements at odd indices (1-based indexing)
    for (let i = 1; i <= n; i++) {
        arr[2 * i - 1] = i;
    }
    
    // Simulate the shifting process
    while (true) {
        let complete = true;
        for (let i = 1; i <= n; i++) {
            if (arr[i] === 0) {
                complete = false;
                break;
            }
        }
        
        if (complete)
            break;
        
        // Find the rightmost occupied cell
        let occupied = -1;
        for (let i = 2 * n - 1; i >= 1; i--) {
            if (arr[i] !== 0) {
                occupied = i;
                break;
            }
        }
        
        // Find nearest empty cell on its left
        let empty = occupied - 1;
        while (empty >= 1 && arr[empty] !== 0) {
            empty--;
        }
        
        arr[empty] = arr[occupied];
        arr[occupied] = 0;
    }
    
    let ans = [];
    for (let idx of queries) {
        ans.push(arr[idx]);
    }
    
    return ans;
}

// Driver code
const n = 4;
const queries = [2, 3, 4];

const ans = findElements(n, queries);

console.log(ans.join(' '));

Output
3 2 4 

[Expected Approach] Recursive Position Mapping - O(n log n) Time and O(log n) Space

The key observation is that the odd positions in the final array always contain the smallest ⌈n/2⌉ numbers in increasing order, so their values can be found directly. For an even position, compress the even indices into consecutive positions (2 -> 1, 4 -> 2, ...). These compressed positions form the same problem for ⌊n/2⌋ elements, so solve it recursively and add an offset of (n + 1) / 2 to get the actual value. If n is odd, adjust the compressed position before making the recursive call.

  • If the queried index is odd, return (idx + 1) / 2.
  • Otherwise, compress the even index using pos = idx / 2.
  • Recursively find the corresponding element for the smaller problem of size n / 2.
  • Add an offset of (n + 1) / 2 to obtain the actual value.
  • If n is odd, adjust the compressed position before the recursive call to account for the cyclic shift.

Consider n = 4 and queries[] = [2, 3, 4].

The final array after all the shifts is: [1, 3, 2, 4], Instead of constructing this array, the recursive function directly computes the value at each queried index.

Query: idx = 2, Since 2 is an even index, we solve it recursively.

  • half = 4 / 2 = 2, pos = 2 / 2 = 1, offset = (4 + 1) / 2 = 2
  • As n is even: findElement(4, 2) = 2 + findElement(2, 1)
  • Now 1 is an odd index, so: findElement(2, 1) = (1 + 1) / 2 = 1. Therefore, findElement(4, 2) = 2 + 1 = 3

Query: idx = 3, Since 3 is an odd index, its value is obtained directly. findElement(4, 3) = (3 + 1) / 2 = 2

Query: idx = 4, Since 4 is an even index:

  • half = 2, pos = 2, offset = 2
  • Recurse on the smaller problem: findElement(4, 4) = 2 + findElement(2, 2)
  • Again, 2 is even: half = 1, pos = 1, offset = 1
  • findElement(2, 2) = 1 + findElement(1, 1)
  • Now 1 is odd: findElement(1, 1) = 1
  • Returning back: findElement(2, 2) = 1 + 1 = 2, findElement(4, 4) = 2 + 2 = 4

Final Answer:

  • Query 2 -> 3, Query 3 -> 2, Query 4 -> 4
  • Hence, the output is: [3, 2, 4]
C++
#include <bits/stdc++.h>
using namespace std;

int findElement(int n, int idx) {

    // Odd positions directly contain the smallest numbers
    if (idx & 1)
        return (idx + 1) / 2;

    int half = n / 2;
    int pos = idx / 2;
    int offset = (n + 1) / 2;

    // Recur on compressed even positions
    if (n & 1) {

        if (pos == 1)
            return offset + findElement(half, half);

        return offset + findElement(half, pos - 1);
    }

    return offset + findElement(half, pos);
}

vector<int> findElements(int n, vector<int>& queries) {

    vector<int> ans;

    for (int idx : queries)
        ans.push_back(findElement(n, idx));

    return ans;
}

int main() {

    int n = 4;
    vector<int> queries = {2, 3, 4};

    vector<int> ans = findElements(n, queries);

    for (int x : ans)
        cout << x << " ";

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

class GfG {
    
    public static int findElement(int n, int idx) {
        
        // Odd positions directly contain the smallest numbers
        if ((idx & 1) == 1) {
            return (idx + 1) / 2;
        }
        
        int half = n / 2;
        int pos = idx / 2;
        int offset = (n + 1) / 2;
        
        // Recur on compressed even positions
        if ((n & 1) == 1) {
            if (pos == 1) {
                return offset + findElement(half, half);
            }
            return offset + findElement(half, pos - 1);
        }
        
        return offset + findElement(half, pos);
    }
    
    public  static ArrayList<Integer> findElements(int n, int[] queries) {
        ArrayList<Integer> ans = new ArrayList<>();
        
        for (int idx : queries) {
            ans.add(findElement(n, idx));
        }
        
        return ans;
    }
    
    public static void main(String[] args) {
        int n = 4;
        int[] queries = {2, 3, 4};
        
        ArrayList<Integer> ans = findElements(n, queries);
        
        for (int x : ans) {
            System.out.print(x + " ");
        }
    }
}
Python
def findElement(n, idx):
    
    # Odd positions directly contain the smallest numbers
    if idx & 1:
        return (idx + 1) // 2
    
    half = n // 2
    pos = idx // 2
    offset = (n + 1) // 2
    
    # Recur on compressed even positions
    if n & 1:
        if pos == 1:
            return offset + findElement(half, half)
        return offset + findElement(half, pos - 1)
    
    return offset + findElement(half, pos)

def findElements(n, queries):
    ans = []
    for idx in queries:
        ans.append(findElement(n, idx))
    return ans

if __name__ == "__main__":
    n = 4
    queries = [2, 3, 4]
    
    ans = findElements(n, queries)
    
    print(' '.join(map(str, ans)))
C#
using System;
using System.Collections.Generic;

class GfG {
    
    public  static int findElement(int n, int idx) {
        
        // Odd positions directly contain the smallest numbers
        if ((idx & 1) == 1) {
            return (idx + 1) / 2;
        }
        
        int half = n / 2;
        int pos = idx / 2;
        int offset = (n + 1) / 2;
        
        // Recur on compressed even positions
        if ((n & 1) == 1) {
            if (pos == 1) {
                return offset + findElement(half, half);
            }
            return offset + findElement(half, pos - 1);
        }
        
        return offset + findElement(half, pos);
    }
    
    public static List<int> findElements(int n, int[] queries) {
        List<int> ans = new List<int>();
        
        foreach (int idx in queries) {
            ans.Add(findElement(n, idx));
        }
        
        return ans;
    }
    
    static void Main(string[] args) {
        int n = 4;
        int[] queries = {2, 3, 4};
        
        List<int> ans = findElements(n, queries);
        
        foreach (int x in ans) {
            Console.Write(x + " ");
        }
    }
}
JavaScript
function findElement(n, idx) {
    
    // Odd positions directly contain the smallest numbers
    if (idx & 1) {
        return Math.floor((idx + 1) / 2);
    }
    
    let half = Math.floor(n / 2);
    let pos = Math.floor(idx / 2);
    let offset = Math.floor((n + 1) / 2);
    
    // Recur on compressed even positions
    if (n & 1) {
        if (pos === 1) {
            return offset + findElement(half, half);
        }
        return offset + findElement(half, pos - 1);
    }
    
    return offset + findElement(half, pos);
}

function findElements(n, queries) {
    let ans = [];
    for (let idx of queries) {
        ans.push(findElement(n, idx));
    }
    return ans;
}

// Driver code
const n = 4;
const queries = [2, 3, 4];
const ans = findElements(n, queries);

console.log(ans.join(' '));

Output
3 2 4 
Comment