Given an array arr[] consisting of distinct elements and a number x, arrange array elements according to the absolute difference with x, i. e., an element having minimum difference comes first, and so on.
Note: If two or more elements are at equal distances arrange them in the same sequence as in the given array.
Examples:
Input: x = 7, arr[] = [10, 5, 3, 9, 2]
Output: [5, 9, 10, 3, 2]
Explanation: abs(7 - 10) = 3, 7 - 5 = 2, 7 - 3 = 4 , abs(7 - 9) = 2 and 7 - 2 = 5,So according to the difference with X, elements are arranged as 5, 9, 10, 3, 2.Input: x = 6, arr[] = [1, 2, 3, 4, 5]
Output: [5, 4, 3, 2, 1]
Explanation: When sorted on the basis of absolute difference with x the elements will be sorted in the given order.
Table of Content
[Approach 1] Using self-balancing BST - O(n × logn) Time and O(n) Space
The idea is to use a self-balancing binary search tree. We traverse the input array and for every element, we find its difference with x and store the difference as key and element as the value in a self-balancing binary search tree. Finally, we traverse the tree and print its inorder traversal which is the required output.
Step-By-Step Approach:
- Store the values in the multimap with the difference with X as key.
- In multimap, the values will be already in sorted order according to key i.e. difference with X because it implements self-balancing-binary-search-tree internally.
- Update all the values of an array with the values of the map so that the array has the required output.
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
void rearrange(vector<int> &arr, int x) {
int n = arr.size();
multimap<int, int> m;
multimap<int, int>::iterator it;
// Store values in a map with the difference
// with X as key
for (int i = 0; i < n; i++)
m.insert(make_pair(abs(x - arr[i]), arr[i]));
// Update the values of array
int i = 0;
for (it = m.begin(); it != m.end(); it++)
arr[i++] = (*it).second;
}
int main() {
vector<int> arr = { 10, 5, 3, 9, 2 };
int x = 7;
rearrange(arr, x);
for (int i = 0; i < arr.size(); i++)
cout << arr[i] << " ";
return 0;
}
import java.util.Map;
import java.util.TreeMap;
import java.util.ArrayList;
class GfG {
static void rearrange(int[] arr, int x) {
int n = arr.length;
TreeMap<Integer, ArrayList<Integer> > m
= new TreeMap<>();
// Store values in a map with the difference
// with X as key
for (int i = 0; i < n; i++) {
int diff = Math.abs(x - arr[i]);
if (m.containsKey(diff)) {
ArrayList<Integer> al = m.get(diff);
al.add(arr[i]);
m.put(diff, al);
}
else {
ArrayList<Integer> al = new ArrayList<>();
al.add(arr[i]);
m.put(diff, al);
}
}
// Update the values of array
int index = 0;
for (Map.Entry entry : m.entrySet()) {
ArrayList<Integer> al = m.get(entry.getKey());
for (int i = 0; i < al.size(); i++)
arr[index++] = al.get(i);
}
}
public static void main(String args[]) {
int[] arr = { 10, 5, 3, 9, 2 };
int n = arr.length;
int x = 7;
// Function call
rearrange(arr, x);
for (int i = 0; i < n; i++)
System.out.print(arr[i] + " ");
}
}
def rearrange(arr, x):
n = len(arr)
m = {}
# Store values in a map
# with the difference
# with X as key
for i in range(n):
m[arr[i]] = abs(x - arr[i])
m = {k: v for k, v in sorted(m.items(),
key=lambda item: item[1])}
# Update the values of array
i = 0
for it in m.keys():
arr[i] = it
i += 1
if __name__ == "__main__":
arr = [10, 5, 3, 9, 2]
n = len(arr)
x = 7
rearrange(arr, x)
for i in range(n):
print(arr[i], end=" ")
using System;
using System.Collections.Generic;
class GfG {
static void rearrange(int[] arr, int x) {
int n = arr.Length;
SortedDictionary<int, List<int> > m
= new SortedDictionary<int, List<int> >();
// Store values in a map with the difference
// with X as key
for (int i = 0; i < n; i++) {
int diff = Math.Abs(x - arr[i]);
if (m.ContainsKey(diff)) {
List<int> al = m[diff];
al.Add(arr[i]);
m[diff] = al;
}
else {
List<int> al = new List<int>();
al.Add(arr[i]);
m.Add(diff, al);
}
}
// Update the values of array
int index = 0;
foreach(int entry in m.Keys) {
List<int> al = m[entry];
for (int i = 0; i < al.Count; i++)
arr[index++] = al[i];
}
}
static public void Main() {
int[] arr = { 10, 5, 3, 9, 2 };
int n = arr.Length;
int x = 7;
// Function call
rearrange(arr, x);
for (int i = 0; i < n; i++)
Console.Write(arr[i] + " ");
}
}
function rearrange(arr,n,x) {
let m = new Map();
// Store values in a map with the difference
// with X as key
for (let i = 0; i < n; i++) {
m.set(arr[i],Math.abs(x-arr[i]));
}
let m1 = new Map([...m.entries()].sort((a, b) =>
a[1] - b[1]));
// Update the values of array
let index = 0;
for (let [key, value] of m1.entries()) {
arr[index++] =key
}
}
// Driver code
let arr=[10, 5, 3, 9 ,2];
let n = arr.length;
let x = 7;
rearrange(arr, n, x);
console.log(arr.join(" "));
Output
5 9 10 3 2
Note: In C++, self-balancing-binary-search-tree is implemented by set, map, and multimap. We can't use set here as we have key-value pairs (not only keys). We also can't directly use map also as a single key can belong to multiple values and map allows a single value for a key. So we use multimap which stores key-value pairs and can have multiple values for a key.
[Approach 2] Using Inbuilt Functions - O(n × logn) Time and O(1) Space
In C++, we can use stable_sort(), and write a lambda expression for the custom comparator function. This solution is elegant and far easier to understand. The only challenge in writing the lambda expression is to send the value 'x' into the lambda expression to be able to use it inside the expression. This can be achieved either by operator overloading with the help of a class or using a much simpler capture.
Note: C# does not offer a built-in stable sorting algorithm for arrays; the default Array.Sort method is not guaranteed to be stable.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void rearrange(vector<int> &arr, int x) {
int n = arr.size();
// sort using comparator function
stable_sort(arr.begin(), arr.end(), [x](int a, int b) {
if (abs(a - x) < abs(b - x))
return true;
else
return false;
});
}
int main() {
vector<int> arr = { 10, 5, 3, 9, 2 };
int n = arr.size();
int x = 7;
rearrange(arr, x);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Arrays;
class GfG {
static void rearrange(int[] arr, int x) {
// Sort using comparator function
Integer[] temp = Arrays.stream(arr).boxed()
.toArray(Integer[]::new);
Arrays.sort(temp, (a, b) -> Math.abs(a - x) - Math.abs(b - x));
for (int i = 0; i < arr.length; i++) {
arr[i] = temp[i];
}
}
public static void main(String[] args) {
int[] arr = {10, 5, 3, 9, 2};
int x = 7;
rearrange(arr, x);
for (int num : arr) {
System.out.print(num + " ");
}
}
}
def rearrange(arr, x):
n = len(arr)
# sorting the array using comparator
arr.sort(key = lambda a: abs(a - x) )
arr = [ 10, 5, 3, 9, 2 ];
x = 7;
rearrange(arr, x);
print(*arr)
using System;
class GfG {
static void rearrange(int[] arr, int x) {
int n = arr.Length;
// create array of tuples (value, originalIndex)
// to simulate stable sort
var temp = new Tuple<int, int>[n];
// store original index
for (int i = 0; i < n; i++) {
temp[i] = Tuple.Create(arr[i], i);
}
// Sort using custom comparator on absolute difference
Array.Sort(temp, (a, b) =>
{
int diffA = Math.Abs(a.Item1 - x);
int diffB = Math.Abs(b.Item1 - x);
if (diffA != diffB) {
// sort by absolute difference
return diffA.CompareTo(diffB);
} else {
// maintain original order using original index
return a.Item2.CompareTo(b.Item2);
}
});
// Copy sorted values back to original array
for (int i = 0; i < n; i++) {
arr[i] = temp[i].Item1;
}
}
static void Main() {
int[] arr = { 10, 5, 3, 9, 2 };
int x = 7;
rearrange(arr, x);
foreach (int val in arr)
Console.Write(val + " ");
}
}
function rearrange(arr, x) {
// sort the array using comparator
arr.sort(function(a, b)
{
return Math.abs(a - x) - Math.abs(b - x)
})
}
// Driver code
let arr = [ 10, 5, 3, 9, 2 ];
let n = arr.length
let x = 7;
rearrange(arr, x);
console.log(arr.join(" "))
Output
5 9 10 3 2