Shuffle 2n integers as a1-b1-a2-b2-a3-b3-..bn without using extra space | Set 2
Last Updated :
13 Apr, 2023
Given an array arr[] consisting of 2* N elements in the form of { a1, a2, …, aN, b1, b2, …, bN }, the task is to shuffle the array to {a1, b1, a2, b2, …, an, b1} without using extra space.
Examples :
Input: arr[] = { 1, 3, 5, 2, 4, 6 }
Output: 1 2 3 4 5 6
Explanation:
The output contains the elements in the form of { a1, b1, a2, b2, a3, b3 }.
Input: arr[] = {1, 2, 3, -1, -2, -3, }
Output: 1 -1 2 -2 3 -3
Divide and Conquer-based Approach: If the size of an array is a power of 2, then follow the article Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ……, an, bn} using divide and conquer technique.
Time Complexity: O(N * log(N))
Auxiliary Space: O(1)
Alternate Approach: The above approach will work for all possible values of N by recursively dividing the array such that the length of both halves is even. Follow the steps below to solve the problem:
- Define a recursive function, say shuffle(start, end).
- If array length is divisible by 4, then calculate mid-point of the array, say mid = start + (end – start + 1) / 2.
- Otherwise, mid = start + (end – start + 1) / 2 – 1.
- Calculate mid-points of both subarrays, say mid1 = start + (mid – start)/2, and mid2 = mid + (end – mid + 1) / 2.
- Reverse the subarrays in the ranges [mid1, mid2], [mid1, mid-1], and [mid, mid2 – 1].
- Make recursive calls for subarrays [start, mid – 1] and [mid, end], i.e. shuffle(start, mid – 1) and shuffle(mid, end) respectively.
- Finally, print the array.
Illustration:
Consider an array arr[] = {a1, a2, a3, b1, b2, b3}:
- Split the array into two halves, both of even length, i.e. a1, a2 : a3, b1, b2, b3.
- Reverse the mid of first half to mid of 2nd half, i.e. a1, b1 : a3, a2, b2, b3.
- Now, reverse the mid of first half to mid of subarray [0, 5], a1, b1 : a3, a2, b2, b3.
- Now reverse mid of subarray [0, 5] to mid of 2nd half, a1, b1 : a2, a3, b2, b3.
- Recursively call for arrays {a1, b1}, and {a2, a3, b2, b3}.
- Now the array {a2, a3, b2, b3} modifies to {a2, b2, a3, b3} after applying the above operations.
- Now the arr[] modifies to {a1, b1, a2, b2, a3, b3}.
Below is the implementation of the above approach:
C
#include <stdio.h>
void reverse( int arr[], int start, int end)
{
int mid = (end - start + 1) / 2;
for ( int i = 0; i < mid; i++) {
int temp = arr[start + i];
arr[start + i] = arr[end - i];
arr[end - i] = temp;
}
return ;
}
void shuffleArrayUtil( int arr[], int start, int end)
{
int i;
int l = end - start + 1;
if (l == 2)
return ;
int mid = start + l / 2;
if (l % 4) {
mid -= 1;
}
int mid1 = start + (mid - start) / 2;
int mid2 = mid + (end + 1 - mid) / 2;
reverse(arr, mid1, mid2 - 1);
reverse(arr, mid1, mid - 1);
reverse(arr, mid, mid2 - 1);
shuffleArrayUtil(arr, start, mid - 1);
shuffleArrayUtil(arr, mid, end);
}
void shuffleArray( int arr[], int N,
int start, int end)
{
shuffleArrayUtil(arr, start, end);
for ( int i = 0; i < N; i++)
printf ( "%d " , arr[i]);
}
int main()
{
int arr[] = { 1, 3, 5, 2, 4, 6 };
int N = sizeof (arr) / sizeof (arr[0]);
shuffleArray(arr, N, 0, N - 1);
return 0;
}
|
C++
#include <bits/stdc++.h>
using namespace std;
void reverse( int arr[], int start, int end)
{
int mid = (end - start + 1) / 2;
for ( int i = 0; i < mid; i++) {
int temp = arr[start + i];
arr[start + i] = arr[end - i];
arr[end - i] = temp;
}
return ;
}
void shuffleArrayUtil( int arr[], int start, int end)
{
int i;
int l = end - start + 1;
if (l == 2)
return ;
int mid = start + l / 2;
if (l % 4) {
mid -= 1;
}
int mid1 = start + (mid - start) / 2;
int mid2 = mid + (end + 1 - mid) / 2;
reverse(arr, mid1, mid2 - 1);
reverse(arr, mid1, mid - 1);
reverse(arr, mid, mid2 - 1);
shuffleArrayUtil(arr, start, mid - 1);
shuffleArrayUtil(arr, mid, end);
}
void shuffleArray( int arr[], int N, int start, int end)
{
shuffleArrayUtil(arr, start, end);
for ( int i = 0; i < N; i++)
cout << arr[i] << " " ;
}
int main()
{
int arr[] = { 1, 3, 5, 2, 4, 6 };
int N = sizeof (arr) / sizeof (arr[0]);
shuffleArray(arr, N, 0, N - 1);
return 0;
}
|
Java
class GFG{
static void reverse( int arr[], int start, int end)
{
int mid = (end - start + 1 ) / 2 ;
for ( int i = 0 ; i < mid; i++)
{
int temp = arr[start + i];
arr[start + i] = arr[end - i];
arr[end - i] = temp;
}
return ;
}
static void shuffleArrayUtil( int arr[], int start, int end)
{
int i;
int l = end - start + 1 ;
if (l == 2 )
return ;
int mid = start + l / 2 ;
if (l % 4 > 0 )
{
mid -= 1 ;
}
int mid1 = start + (mid - start) / 2 ;
int mid2 = mid + (end + 1 - mid) / 2 ;
reverse(arr, mid1, mid2 - 1 );
reverse(arr, mid1, mid - 1 );
reverse(arr, mid, mid2 - 1 );
shuffleArrayUtil(arr, start, mid - 1 );
shuffleArrayUtil(arr, mid, end);
}
static void shuffleArray( int arr[], int N,
int start, int end)
{
shuffleArrayUtil(arr, start, end);
for ( int i = 0 ; i < N; i++)
System.out.printf( "%d " , arr[i]);
}
public static void main(String[] args)
{
int arr[] = { 1 , 3 , 5 , 2 , 4 , 6 };
int N = arr.length;
shuffleArray(arr, N, 0 , N - 1 );
}
}
|
Python3
def reverse(arr, start, end):
mid = (end - start + 1 ) / / 2
for i in range (mid):
temp = arr[start + i]
arr[start + i] = arr[end - i]
arr[end - i] = temp
return arr
def shuffleArrayUtil(arr, start, end):
i = 0
l = end - start + 1
if (l = = 2 ):
return
mid = start + l / / 2
if (l % 4 ):
mid - = 1
mid1 = start + (mid - start) / / 2
mid2 = mid + (end + 1 - mid) / / 2
arr = reverse(arr, mid1, mid2 - 1 )
arr = reverse(arr, mid1, mid - 1 )
arr = reverse(arr, mid, mid2 - 1 )
shuffleArrayUtil(arr, start, mid - 1 )
shuffleArrayUtil(arr, mid, end)
def shuffleArray(arr, N, start, end):
shuffleArrayUtil(arr, start, end)
for i in arr:
print (i, end = " " )
if __name__ = = '__main__' :
arr = [ 1 , 3 , 5 , 2 , 4 , 6 ]
N = len (arr)
shuffleArray(arr, N, 0 , N - 1 )
|
C#
using System;
public class GFG{
static void reverse( int [] arr, int start, int end)
{
int mid = (end - start + 1) / 2;
for ( int i = 0; i < mid; i++)
{
int temp = arr[start + i];
arr[start + i] = arr[end - i];
arr[end - i] = temp;
}
return ;
}
static void shuffleArrayUtil( int [] arr, int start, int end)
{
int l = end - start + 1;
if (l == 2)
return ;
int mid = start + l / 2;
if (l % 4 > 0)
{
mid -= 1;
}
int mid1 = start + (mid - start) / 2;
int mid2 = mid + (end + 1 - mid) / 2;
reverse(arr, mid1, mid2 - 1);
reverse(arr, mid1, mid - 1);
reverse(arr, mid, mid2 - 1);
shuffleArrayUtil(arr, start, mid - 1);
shuffleArrayUtil(arr, mid, end);
}
static void shuffleArray( int [] arr, int N,
int start, int end)
{
shuffleArrayUtil(arr, start, end);
for ( int i = 0; i < N; i++)
Console.Write(arr[i] + " " );
}
static public void Main ()
{
int [] arr = { 1, 3, 5, 2, 4, 6 };
int N = arr.Length;
shuffleArray(arr, N, 0, N - 1);
}
}
|
Javascript
<script>
function reverse(arr, start, end)
{
let mid = (end - start + 1) / 2;
for (let i = 0; i < mid; i++)
{
let temp = arr[start + i];
arr[start + i] = arr[end - i];
arr[end - i] = temp;
}
return ;
}
function shuffleArrayUtil(arr, start, end)
{
let i;
let l = end - start + 1;
if (l == 2)
return ;
let mid = start + l / 2;
if (l % 4 > 0)
{
mid -= 1;
}
let mid1 = start + (mid - start) / 2;
let mid2 = mid + (end + 1 - mid) / 2;
reverse(arr, mid1, mid2 - 1);
reverse(arr, mid1, mid - 1);
reverse(arr, mid, mid2 - 1);
shuffleArrayUtil(arr, start, mid - 1);
shuffleArrayUtil(arr, mid, end);
}
function shuffleArray(arr, N,
start, end)
{
shuffleArrayUtil(arr, start, end);
for (let i = 0; i < N; i++)
document.write(arr[i] + " " );
}
let arr = [ 1, 3, 5, 2, 4, 6 ];
let N = arr.length;
shuffleArray(arr, N, 0, N - 1);
</script>
|
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...