Given two arrays a and b of equal length, pair each element of array a to an element in array b, such that the sum of the absolute differences of all the pairs is minimum
Examples:
Input: a = [4, 1, 2], b = [2, 4, 1]
Output: 0
Explanation: If we take the pairings as (4,4), (1,1), and (2,2),
the sum will be S = |4 - 4| + |1 - 1| +|2 - 2| = 0.
It can be shown that this is the minimum sum we can get.
Input: a = [4, 1, 8, 7], b = [2, 3, 6, 5]
Output: 6
Explanation:If we take the pairings as (1,2), (4,3), (7,5), and (8,6),
the sum will be S = |1 - 2| + |4 - 3| + |7 - 5| + |8 - 6| = 6.
It can be shown that this is the minimum sum we can get.
Table of Content
[Naive Approach] Try All Permutations - O(n*n!) Time O(n) Space
Try all permutations of b[] to be mapped with a[]. We first pair an element of b[] with a[], recursively call for the remaining array and then backtrack to remove the pairing.
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
// Generate all possible pairings
int solve(vector<int> &a, vector<int> &b,
vector<bool> &used,
int idx)
{
int n = a.size();
// All elements paired
if (idx == n)
return 0;
int res = INT_MAX;
// Try pairing a[idx] with every unused b[j]
for (int j = 0; j < n; j++)
{
if (!used[j])
{
used[j] = true;
int curr = abs(a[idx] - b[j]) +
solve(a, b, used, idx + 1);
res = min(res, curr);
used[j] = false;
}
}
return res;
}
int findMinSum(vector<int> &a, vector<int> &b)
{
int n = a.size();
// To track used elements in b
vector<bool> used(n, false);
return solve(a, b, used, 0);
}
int main()
{
vector<int> a = {4, 1, 8, 7};
vector<int> b = {2, 3, 6, 5};
cout << findMinSum(a, b);
return 0;
}
#include <stdio.h>
#include <limits.h>
// Generate all possible pairings
int solve(int a[], int b[], int used[], int idx, int n) {
// All elements paired
if (idx == n)
return 0;
int res = INT_MAX;
// Try pairing a[idx] with every unused b[j]
for (int j = 0; j < n; j++) {
if (!used[j]) {
used[j] = 1;
int curr = abs(a[idx] - b[j]) +
solve(a, b, used, idx + 1, n);
res = res < curr? res : curr;
used[j] = 0;
}
}
return res;
}
int findMinSum(int a[], int b[], int n) {
int used[n];
for (int i = 0; i < n; i++)
used[i] = 0;
return solve(a, b, used, 0, n);
}
int main() {
int a[] = {4, 1, 8, 7};
int b[] = {2, 3, 6, 5};
int n = sizeof(a) / sizeof(a[0]);
printf("%d", findMinSum(a, b, n));
return 0;
}
import java.util.Arrays;
public class Main {
// Generate all possible pairings
static int solve(int[] a, int[] b, boolean[] used, int idx) {
int n = a.length;
// All elements paired
if (idx == n)
return 0;
int res = Integer.MAX_VALUE;
// Try pairing a[idx] with every unused b[j]
for (int j = 0; j < n; j++) {
if (!used[j]) {
used[j] = true;
int curr = Math.abs(a[idx] - b[j]) +
solve(a, b, used, idx + 1);
res = Math.min(res, curr);
used[j] = false;
}
}
return res;
}
static int findMinSum(int[] a, int[] b) {
int n = a.length;
// To track used elements in b
boolean[] used = new boolean[n];
Arrays.fill(used, false);
return solve(a, b, used, 0);
}
public static void main(String[] args) {
int[] a = {4, 1, 8, 7};
int[] b = {2, 3, 6, 5};
System.out.println(findMinSum(a, b));
}
}
def solve(a, b, used, idx):
n = len(a)
# All elements paired
if idx == n:
return 0
res = float('inf')
# Try pairing a[idx] with every unused b[j]
for j in range(n):
if not used[j]:
used[j] = True
curr = abs(a[idx] - b[j]) + solve(a, b, used, idx + 1)
res = min(res, curr)
used[j] = False
return res
def findMinSum(a, b):
n = len(a)
# To track used elements in b
used = [False] * n
return solve(a, b, used, 0)
if __name__ == '__main__':
a = [4, 1, 8, 7]
b = [2, 3, 6, 5]
print(findMinSum(a, b))
using System;
class Program {
// Generate all possible pairings
static int Solve(int[] a, int[] b, bool[] used, int idx) {
int n = a.Length;
// All elements paired
if (idx == n)
return 0;
int res = int.MaxValue;
// Try pairing a[idx] with every unused b[j]
for (int j = 0; j < n; j++) {
if (!used[j]) {
used[j] = true;
int curr = Math.Abs(a[idx] - b[j]) +
Solve(a, b, used, idx + 1);
res = Math.Min(res, curr);
used[j] = false;
}
}
return res;
}
static int FindMinSum(int[] a, int[] b) {
int n = a.Length;
// To track used elements in b
bool[] used = new bool[n];
return Solve(a, b, used, 0);
}
static void Main() {
int[] a = {4, 1, 8, 7};
int[] b = {2, 3, 6, 5};
Console.WriteLine(FindMinSum(a, b));
}
}
function solve(a, b, used, idx) {
const n = a.length;
// All elements paired
if (idx === n)
return 0;
let res = Number.MAX_SAFE_INTEGER;
// Try pairing a[idx] with every unused b[j]
for (let j = 0; j < n; j++) {
if (!used[j]) {
used[j] = true;
const curr = Math.abs(a[idx] - b[j]) +
solve(a, b, used, idx + 1);
res = Math.min(res, curr);
used[j] = false;
}
}
return res;
}
function findMinSum(a, b) {
const n = a.length;
// To track used elements in b
const used = new Array(n).fill(false);
return solve(a, b, used, 0);
}
const a = [4, 1, 8, 7];
const b = [2, 3, 6, 5];
console.log(findMinSum(a, b));
Output
6
Time Complexity: O(n2)
Space Complexity: O(n)
[Expected Approach] Using Sorting and Greedy Pairing - O(n log n) Time O(1) Space
The idea is to sort both arrays in ascending order so that elements with similar values come closer. Then we pair elements at the same index from both sorted arrays. This greedy strategy ensures that each element is matched with the closest possible value, which minimizes the overall sum of absolute differences.
Let us understand step by step with an example:
Input: a = [4, 1, 8, 7], b = [2, 3, 6, 5]
Sort both arrays in ascending order: a -> [1, 4, 7, 8], b -> [2, 3, 5, 6]
Initialize sum = 0
Start traversing both arrays and form pairs at same index:
- For i = 0, Pair formed = (1, 2), Compute difference = |1 - 2| = 1, Update sum = 1
- For i = 1, Pair formed = (4, 3), Compute difference = |4 - 3| = 1, Update sum = 2
- For i = 2, Pair formed = (7, 5), Compute difference = |7 - 5| = 2, Update sum = 4
- For i = 3, Pair formed = (8, 6), Compute difference = |8 - 6| = 2, Update sum = 6
After completing traversal, Minimum sum of absolute differences = 6
#include <bits/stdc++.h>
using namespace std;
// Returns minimum possible pairwise absolute
// difference of two arrays.
int findMinSum(vector<int> &a, vector<int> &b)
{
int n = a.size();
int sum = 0;
// Sort both arrays in ascending order
sort(a.begin(), a.end());
sort(b.begin(), b.end());
// Calculate sum of absolute differences
for (int i = 0; i < n; i++)
{
sum += abs(a[i] - b[i]);
}
return sum;
}
// Driver code
int main()
{
vector<int> a = {4, 1, 8, 7};
vector<int> b = {2, 3, 6, 5};
cout << findMinSum(a, b);
return 0;
}
import java.util.*;
import java.util.stream.*;
import java.util.function.*;
// Returns minimum possible pairwise absolute
// difference of two arrays.
public class GfG {
public static int findMinSum(int[] a, int[] b) {
int n = a.length;
int sum = 0;
// Sort both arrays in ascending order
Arrays.sort(a);
Arrays.sort(b);
// Calculate sum of absolute differences
for (int i = 0; i < n; i++) {
sum += Math.abs(a[i] - b[i]);
}
return sum;
}
// Driver code
public static void main(String[] args) {
int[] a = {4, 1, 8, 7};
int[] b = {2, 3, 6, 5};
System.out.println(findMinSum(a, b));
}
}
from typing import List
# Returns minimum possible pairwise absolute
# difference of two arrays.
def findMinSum(a: List[int], b: List[int]) -> int:
n = len(a)
sum = 0
# Sort both arrays in ascending order
a.sort()
b.sort()
# Calculate sum of absolute differences
for i in range(n):
sum += abs(a[i] - b[i])
return sum
# Driver code
if __name__ == "__main__":
a = [4, 1, 8, 7]
b = [2, 3, 6, 5]
print(findMinSum(a, b))
using System;
class GfG
{
// Returns minimum possible pairwise absolute difference
static int findMinSum(int[] a, int[] b)
{
int n = a.Length;
int sum = 0;
// Sort both arrays
Array.Sort(a);
Array.Sort(b);
// Calculate sum of absolute differences
for (int i = 0; i < n; i++)
{
sum += Math.Abs(a[i] - b[i]);
}
return sum;
}
// Driver code
static void Main(string[] args)
{
int[] a = { 4, 1, 8, 7 };
int[] b = { 2, 3, 6, 5 };
Console.WriteLine(findMinSum(a, b));
}
}
// Returns minimum possible pairwise absolute
// difference of two arrays.
function findMinSum(a, b) {
let n = a.length;
let sum = 0;
// Sort both arrays in ascending order
a.sort((x, y) => x - y);
b.sort((x, y) => x - y);
// Calculate sum of absolute differences
for (let i = 0; i < n; i++) {
sum += Math.abs(a[i] - b[i]);
}
return sum;
}
// Driver code
let a = [4, 1, 8, 7];
let b = [2, 3, 6, 5];
console.log(findMinSum(a, b));
Output
6
Time Complexity: O(n log n)
Auxiliary Space: O(1)