Given an array arr[] of size N (N is even) and a positive integer K, the task is to apply an operation to the array arr[] for K times. Applying the operation once will shift all the even indexed numbers to the beginning and all the odd indexed numbers to the end, maintaining their relative order.
Examples:
Input: K = 1, N = 6, arr[] = {1, 2, 3, 4, 5, 6}
Output: {1, 3, 5, 2, 4, 6}
Explanation: Applying the operation once would be equal to arr'[] = {arr[0], arr[2], arr[4], arr[1], arr[3], arr[5]} = {1, 3, 5, 2, 4, 6}Input: K = 2, N = 10, arr[]= {20, 123, 23, 21, 33, 13, 55, 65, 90, 100}
Output: {20, 33, 90, 21, 65, 23, 55, 123, 13, 100}
Explanation: Applying the operation once would be equal to arr'[] = {arr[0], arr[2], arr[4], arr[6], arr[8], arr[1], arr[3], arr[5], arr[7], arr[9]} = {20, 23, 33, 55, 90, 123, 21, 13, 65, 100} and applying it again would be equal to arr''[] = {20, 33, 90, 21, 65, 23, 55, 123, 13, 100}
Approach: The problem can be solved using the following approach:
If we observe carefully, shifting all the even indexed numbers to the beginning and odd indexed integers to the end is same as applying a permutation P to S where P = [0, 2, 4, 6, ... N-2, 1, 3, 5, ...N-1]. So we can get our answer by simply applying the permutation P to S for K times. This can be simply done in log2(K) time using Binary Exponentiation.
Step-by-step approach:
- Declare a permutation P = [0, 2, 4, 6, ... N-2, 1, 3, 5, ...N-1].
- Initialise a function apply(S, P) which applies the permutation P to the array arr[], and stores it back to arr[].
- Use Binary exponentiation to reduce the number of operations to log2K time.
- If K is odd, apply permutation P to array arr[], apply(arr, P)
- Then apply permutation P to itself, apply(P, P)
- Reduce K to half
- Keep doing the above steps till K is greater than 0
- Return the answer as arr[].
Below is the implementation of the above approach:
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
// function to apply a permutation P to a Sequence arr
void apply(vector<ll>& arr, vector<ll>& P)
{
vector<ll> temp(arr.size());
for (int i = 1; i < arr.size(); i++) {
temp[i] = arr[P[i]];
}
for (int i = 1; i < arr.size(); i++)
arr[i] = temp[i];
}
// Function to perform the operation to Sequence arr
// K number of times
void solve(ll N, ll K, vector<ll>& arr)
{
// vector to store the permutation
vector<ll> P;
for (int i = 0; i < N; i += 2)
P.push_back(i);
for (int i = 1; i < N; i += 2)
P.push_back(i);
// binary exponentiation
while (K) {
if (K & 1)
apply(arr, P);
apply(P, P);
K >>= 1;
}
// Printing the final sequence
for (int i = 0; i < N; i++)
cout << arr[i] << " ";
cout << "\n";
}
int main()
{
ll N = 10, K = 2;
vector<ll> arr
= { 20, 123, 23, 21, 33, 13, 55, 65, 90, 100 };
solve(N, K, arr);
// your code goes here
return 0;
}
import java.util.ArrayList;
public class Main {
// Function to apply permutation P to the array arr
static void apply(ArrayList<Long> arr, ArrayList<Long> P) {
ArrayList<Long> temp = new ArrayList<>(arr.size());
// Create a temporary array to store the permuted values
for (int i = 0; i < arr.size(); i++) {
temp.add(arr.get((int) (long) P.get(i)));
}
// Copy values from temp back to arr
for (int i = 0; i < arr.size(); i++) {
arr.set(i, temp.get(i));
}
}
// Function to solve the problem
static void solve(long N, long K, ArrayList<Long> arr) {
// Generate permutation P for swapping even and odd indices
ArrayList<Long> P = new ArrayList<>();
for (int i = 0; i < N; i += 2) {
P.add((long) i);
}
for (int i = 1; i < N; i += 2) {
P.add((long) i);
}
// Apply the permutation P K times
while (K > 0) {
if ((K & 1) == 1) {
apply(arr, P);
}
apply(P, P);
K >>= 1; // Right shift K to divide by 2
}
// Print the final array
for (int i = 0; i < N; i++) {
System.out.print(arr.get(i) + " ");
}
System.out.println();
}
// Main function
public static void main(String[] args) {
// Example usage
long N = 10, K = 2;
ArrayList<Long> arr = new ArrayList<>();
arr.add(20L);
arr.add(123L);
arr.add(23L);
arr.add(21L);
arr.add(33L);
arr.add(13L);
arr.add(55L);
arr.add(65L);
arr.add(90L);
arr.add(100L);
solve(N, K, arr);
}
}
def apply(arr, P):
# Function to apply permutation P to the sequence arr
temp = [0] * len(arr)
for i in range(1, len(arr)):
temp[i] = arr[P[i]]
for i in range(1, len(arr)):
arr[i] = temp[i]
def solve(N, K, arr):
# Function to perform the operation on sequence arr K times
# Vector to store the permutation P
P = []
for i in range(0, N, 2):
P.append(i)
for i in range(1, N, 2):
P.append(i)
# Binary exponentiation
while K:
if K & 1:
# If the least significant bit of K is set, apply permutation to arr
apply(arr, P)
# Square the permutation P
apply(P, P)
# Right shift K to divide it by 2
K >>= 1
# Printing the final sequence
print(*arr)
# Driver code
if __name__ == "__main__":
N = 10
K = 2
arr = [20, 123, 23, 21, 33, 13, 55, 65, 90, 100]
# Function call
solve(N, K, arr)
using System;
using System.Collections.Generic;
public class Program
{
// function to apply a permutation P to a Sequence arr
private static void Apply(List<long> arr, List<long> P)
{
List<long> temp = new List<long>(arr.Count);
for (int i = 0; i < arr.Count; i++)
{
temp.Add(arr[(int)P[i]]);
}
for (int i = 0; i < arr.Count; i++)
{
arr[i] = temp[i];
}
}
// Function to perform the operation to Sequence arr
// K number of times
private static void Solve(long N, long K, List<long> arr)
{
// vector to store the permutation
List<long> P = new List<long>();
for (int i = 0; i < N; i += 2)
{
P.Add(i);
}
for (int i = 1; i < N; i += 2)
{
P.Add(i);
}
// binary exponentiation
while (K > 0)
{
if ((K & 1) == 1)
{
Apply(arr, P);
}
Apply(P, P);
K >>= 1;
}
// Printing the final sequence
foreach (long num in arr)
{
Console.Write(num + " ");
}
Console.WriteLine();
}
public static void Main(string[] args)
{
long N = 10, K = 2;
List<long> arr = new List<long> { 20, 123, 23, 21, 33, 13, 55, 65, 90, 100 };
Solve(N, K, arr);
}
}
//This code is contributed by adarsh
function apply(arr, P) {
// Function to apply permutation P to the sequence arr
const temp = Array(arr.length).fill(0);
for (let i = 1; i < arr.length; i++) {
temp[i] = arr[P[i]];
}
for (let i = 1; i < arr.length; i++) {
arr[i] = temp[i];
}
}
function solve(N, K, arr) {
// Function to perform the operation on sequence arr K times
// Vector to store the permutation P
const P = [];
for (let i = 0; i < N; i += 2) {
P.push(i);
}
for (let i = 1; i < N; i += 2) {
P.push(i);
}
// Binary exponentiation
while (K) {
if (K & 1) {
// If the least significant bit of K is set,
// apply permutation to arr
apply(arr, P);
}
// Square the permutation P
apply(P, P);
// Right shift K to divide it by 2
K >>= 1;
}
// Printing the final sequence
console.log(...arr);
}
// Driver code
const N = 10;
const K = 2;
const arr = [20, 123, 23, 21, 33, 13, 55, 65, 90, 100];
// Function call
solve(N, K, arr);
Output
20 33 90 21 65 23 55 123 13 100
Time Complexity: O(N * log2K) where N is the length of the input sequence S and K is the number of operations to be performed
Auxiliary Space: O(N) to store the permutation