Given an array arr[] of positive integers. The task is to rearrange the array elements alternatively i.e. first element should be the max value, the second should be the min value, the third should be the second max, the fourth should be the second min, and so on.
Examples:
Input: arr[] = [1, 2, 3, 4, 5, 6]
Output: [6, 1, 5, 2, 4, 3]
Explanation: Max element = 6, min = 1, second max = 5, second min = 2, and so on...
The modified array is: [6, 1, 5, 2, 4, 3]
Input: arr[]= [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110]
Output: [110, 10, 100, 20, 90, 30, 80, 40, 70, 50, 60]
Explanation: Max element = 110, min = 10, second max = 100, second min = 20, and so on...
The Modified array is : [110, 10, 100, 20, 90, 30, 80, 40, 70, 50, 60]
Table of Content
Using Two Pointer Technique with Auxiliary Array - O(n log n) Time O(n) Space
The idea is to use an auxiliary array. We maintain two pointers one to the leftmost or smallest element and the other to the rightmost or largest element. We move both pointers toward each other and alternatively copy elements at these pointers to an auxiliary array. Finally, we copy the auxiliary array back to the original array.
Working of Approach:
#include <bits/stdc++.h>
using namespace std;
// Function to rearrange the array elements alternately
void rearrange(vector<int> &arr)
{
int n = arr.size();
// Sort the array
sort(arr.begin(), arr.end());
// Auxiliary array to hold modified array
vector<int> temp(n);
// Indexes of smallest and largest elements
// from remaining array.
int small = 0, large = n - 1;
// To indicate whether we need to copy remaining
// largest or remaining smallest at next position
int flag = true;
// Store result in temp[]
for (int i = 0; i < n; i++)
{
if (flag)
temp[i] = arr[large--];
else
temp[i] = arr[small++];
flag = !flag;
}
// Copy temp[] to arr[]
for (int i = 0; i < n; i++)
arr[i] = temp[i];
}
// Driver Code
int main()
{
vector<int> arr = {1, 2, 3, 4, 5, 6};
rearrange(arr);
for (int i = 0; i < arr.size(); i++)
cout << arr[i] << " ";
return 0;
}
import java.util.Arrays;
// Function to rearrange the array elements alternately
public class GfG {
public static void rearrange(int[] arr) {
int n = arr.length;
// Sort the array
Arrays.sort(arr);
// Auxiliary array to hold modified array
int[] temp = new int[n];
// Indexes of smallest and largest elements
// from remaining array.
int small = 0, large = n - 1;
// To indicate whether we need to copy remaining
// largest or remaining smallest at next position
boolean flag = true;
// Store result in temp[]
for (int i = 0; i < n; i++) {
if (flag)
temp[i] = arr[large--];
else
temp[i] = arr[small++];
flag = !flag;
}
// Copy temp[] to arr[]
for (int i = 0; i < n; i++)
arr[i] = temp[i];
}
// Driver Code
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6};
rearrange(arr);
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
}
}
from typing import List
# Function to rearrange the array elements alternately
def rearrange(arr: List[int]) -> None:
n = len(arr)
# Sort the array
arr.sort()
# Auxiliary array to hold modified array
temp = [0] * n
# Indexes of smallest and largest elements
# from remaining array.
small = 0
large = n - 1
# To indicate whether we need to copy remaining
# largest or remaining smallest at next position
flag = True
# Store result in temp[]
for i in range(n):
if flag:
temp[i] = arr[large]
large -= 1
else:
temp[i] = arr[small]
small += 1
flag = not flag
# Copy temp[] to arr[]
for i in range(n):
arr[i] = temp[i]
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5, 6]
rearrange(arr)
for i in range(len(arr)):
print(arr[i], end=' ')
using System;
class GfG
{
// Function to rearrange the array elements alternately
static void rearrange(int[] arr)
{
int n = arr.Length;
// Sort the array
Array.Sort(arr);
// Auxiliary array to hold modified array
int[] temp = new int[n];
// Indexes of smallest and largest elements
// from remaining array.
int small = 0, large = n - 1;
// To indicate whether we need to copy remaining
// largest or remaining smallest at next position
bool flag = true;
// Store result in temp[]
for (int i = 0; i < n; i++)
{
if (flag)
temp[i] = arr[large--];
else
temp[i] = arr[small++];
flag = !flag;
}
// Copy temp[] to arr[]
for (int i = 0; i < n; i++)
arr[i] = temp[i];
}
// Driver Code
static void Main()
{
int[] arr = {1, 2, 3, 4, 5, 6};
rearrange(arr);
for (int i = 0; i < arr.Length; i++)
Console.Write(arr[i] + " ");
}
}
// Function to rearrange the array elements alternately
function rearrange(arr) {
let n = arr.length;
// Sort the array
arr.sort((a, b) => a - b);
// Auxiliary array to hold modified array
let temp = new Array(n);
// Indexes of smallest and largest elements
// from remaining array.
let small = 0, large = n - 1;
// To indicate whether we need to copy remaining
// largest or remaining smallest at next position
let flag = true;
// Store result in temp[]
for (let i = 0; i < n; i++) {
if (flag)
temp[i] = arr[large--];
else
temp[i] = arr[small++];
flag =!flag;
}
// Copy temp[] to arr[]
for (let i = 0; i < n; i++)
arr[i] = temp[i];
}
// Driver Code
let arr = [1, 2, 3, 4, 5, 6];
rearrange(arr);
for (let i = 0; i < arr.length; i++)
console.log(arr[i] + ' ');
Output
6 1 5 2 4 3
Time Complexity: O(n log n)
Auxiliary Space: O(n)
Using Modular Arithmetic - O(n log n) Time O(1) Space
The idea is to use multiplication and modular arithmetic to store two elements at each index. Assume m = maximum element in the array + 1. Now, if we want to store two numbers say x and y at any index, then we can store x + (y * m) at that index. This will work because using x + (y * m), we can get the first value by using modulo: (x + (y * m)) mod m = x and the second value by using (x + (y * m)) / m = y.
To arrange the elements alternately, we can maintain two pointers min_idx = 0 to keep track of the next minimum element and max_idx = n - 1 to keep track of the next maximum element. Now, iterate from i = 0 to n - 1,
- If i is even, then we need to place maximum remaining element, so update arr[i] = arr[i] + (arr[max_idx] % m) * m and decrement max_idx by 1. Now, arr[i] has arr[i] as well as arr[max_idx] as its value.
- If i is odd, then we need to place minimum remaining element, so update arr[i] = arr[i] + (arr[min_idx] % m) * m and increment min_idx by 1. Now, arr[i] has arr[i] as well as arr[min_idx] as its value.
- Finally, traverse the array again and divide every element by m to get the required rearranged elements.
Working of Approach:
#include <bits/stdc++.h>
using namespace std;
// Function to rearrange array alternately
void rearrange(vector<int> &arr)
{
int n = arr.size();
// Sort the array
sort(arr.begin(), arr.end());
// Initialize index of first minimum and first
// maximum element
int max_idx = n - 1, min_idx = 0;
// Store maximum element of array
int m = arr[n - 1] + 1;
// Traverse array elements
for (int i = 0; i < n; i++)
{
// At even index : we have to put maximum element
if (i % 2 == 0)
{
arr[i] += (arr[max_idx] % m) * m;
max_idx--;
}
// At odd index : we have to put minimum element
else
{
arr[i] += (arr[min_idx] % m) * m;
min_idx++;
}
}
// Reduce array elements to store the new value
for (int i = 0; i < n; i++)
arr[i] = arr[i] / m;
}
// Driver Code
int main()
{
vector<int> arr = {1, 2, 3, 4, 5, 6};
rearrange(arr);
for (int i = 0; i < arr.size(); i++)
cout << arr[i] << " ";
return 0;
}
import java.util.Arrays;
// Function to rearrange array alternately
public class GfG {
public static void rearrange(int[] arr) {
int n = arr.length;
// Sort the array
Arrays.sort(arr);
// Initialize index of first minimum and first
// maximum element
int max_idx = n - 1, min_idx = 0;
// Store maximum element of array
int m = arr[n - 1] + 1;
// Traverse array elements
for (int i = 0; i < n; i++) {
// At even index : we have to put maximum element
if (i % 2 == 0) {
arr[i] += (arr[max_idx] % m) * m;
max_idx--;
}
// At odd index : we have to put minimum element
else {
arr[i] += (arr[min_idx] % m) * m;
min_idx++;
}
}
// Reduce array elements to store the new value
for (int i = 0; i < n; i++)
arr[i] = arr[i] / m;
}
// Driver Code
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6};
rearrange(arr);
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
}
}
def rearrange(arr):
n = len(arr)
# Sort the array
arr.sort()
# Initialize index of first minimum and first
# maximum element
max_idx = n - 1
min_idx = 0
# Store maximum element of array
m = arr[n - 1] + 1
# Traverse array elements
for i in range(n):
# At even index : we have to put maximum element
if i % 2 == 0:
arr[i] += (arr[max_idx] % m) * m
max_idx -= 1
# At odd index : we have to put minimum element
else:
arr[i] += (arr[min_idx] % m) * m
min_idx += 1
# Reduce array elements to store the new value
for i in range(n):
arr[i] = arr[i] // m
# Driver Code
if __name__ == '__main__':
arr = [1, 2, 3, 4, 5, 6]
rearrange(arr)
for i in range(len(arr)):
print(arr[i], end=' ')
using System;
class GfG
{
// Function to rearrange array alternately
static void rearrange(int[] arr)
{
int n = arr.Length;
// Sort the array
Array.Sort(arr);
// Initialize index of first minimum and first
// maximum element
int max_idx = n - 1, min_idx = 0;
// Store maximum element of array
int m = arr[n - 1] + 1;
// Traverse array elements
for (int i = 0; i < n; i++)
{
// At even index : we have to put maximum element
if (i % 2 == 0)
{
arr[i] += (arr[max_idx] % m) * m;
max_idx--;
}
// At odd index : we have to put minimum element
else
{
arr[i] += (arr[min_idx] % m) * m;
min_idx++;
}
}
// Reduce array elements to store the new value
for (int i = 0; i < n; i++)
arr[i] = arr[i] / m;
}
// Driver Code
static void Main()
{
int[] arr = {1, 2, 3, 4, 5, 6};
rearrange(arr);
for (int i = 0; i < arr.Length; i++)
Console.Write(arr[i] + " ");
}
}
// Function to rearrange array alternately
function rearrange(arr) {
let n = arr.length;
// Sort the array
arr.sort((a, b) => a - b);
// Initialize index of first minimum and first
// maximum element
let max_idx = n - 1, min_idx = 0;
// Store maximum element of array
let m = arr[n - 1] + 1;
// Traverse array elements
for (let i = 0; i < n; i++) {
// At even index : we have to put maximum element
if (i % 2 == 0) {
arr[i] += (arr[max_idx] % m) * m;
max_idx--;
}
// At odd index : we have to put minimum element
else {
arr[i] += (arr[min_idx] % m) * m;
min_idx++;
}
}
// Reduce array elements to store the new value
for (let i = 0; i < n; i++)
arr[i] = Math.floor(arr[i] / m);
}
// Driver Code
let arr = [1, 2, 3, 4, 5, 6];
rearrange(arr);
for (let i = 0; i < arr.length; i++)
console.log(arr[i] + " ");
Output
6 1 5 2 4 3
Time Complexity: O(n log n)
Auxiliary Space: O(1)