Given an array arr[] of length N, the task is to find the median of the differences of all pairs of the array elements.
Example:
Input: arr[] = {1, 2, 3, 4}
Output: 1
Explanation:
The difference of all pairs from the given array are {2 – 1, 3 – 2, 4 – 3, 3 – 1, 4 – 2, 4 – 1} = {1, 1, 1, 2, 2, 3}.
Since the array contains 6 elements, the median is the element at index 3 of the difference array.
Therefore, the answer is 1.
Input: arr[] = {1, 3, 5}
Output: 2
Explanation: The difference array is {2, 2, 4}. Therefore, the median is 2.
Naive Approach: The task is to generate all possible pairs from the given array and calculate the difference of every pair in the array arr[] and store them in the array diff[]. Sort diff[] and find the middle element.
Time Complexity: O(N2*log(N2))
Auxiliary Space: O(N2)
Efficient Approach: The above approach can be optimized using Binary Search and Sorting. Follow the below steps to solve the problem:
- Sort the given array.
- Initialize low=0 and high=arr[N-1]-arr[0].
- Calculate mid-equal to (low + high) / 2.
- Calculate the number of differences less than mid. If it exceeds the median index of the difference array, [ceil(N * (N – 1) / 2)], then update high as mid – 1. Otherwise, update low as mid + 1.
- Repeat the above steps until low and high becomes equal.
Below is the implementation above approach:
C++
#include <bits/stdc++.h>
#define ll long long
using namespace std;
bool possible(ll mid, vector<ll>& a)
{
ll n = a.size();
ll total = (n * (n - 1)) / 2;
ll need = (total + 1) / 2;
ll count = 0;
ll start = 0, end = 1;
while (end < n) {
if (a[end] - a[start] <= mid) {
end++;
}
else {
count += (end - start - 1);
start++;
}
}
if (end == n && start < end
&& a[end - 1] - a[start] <= mid) {
ll t = end - start - 1;
count += (t * (t + 1) / 2);
}
if (count >= need)
return true ;
else
return false ;
}
ll findMedian(vector<ll>& a)
{
ll n = a.size();
ll low = 0, high = a[n - 1] - a[0];
while (low <= high) {
ll mid = (low + high) / 2;
if (possible(mid, a))
high = mid - 1;
else
low = mid + 1;
}
return high + 1;
}
int main()
{
vector<ll> a = { 1, 7, 5, 2 };
sort(a.begin(), a.end());
cout << findMedian(a) << endl;
}
|
Java
import java.util.*;
class GFG{
static boolean possible( long mid, int [] a)
{
long n = a.length;
long total = (n * (n - 1 )) / 2 ;
long need = (total + 1 ) / 2 ;
long count = 0 ;
long start = 0 , end = 1 ;
while (end < n)
{
if (a[( int )end] - a[( int )start] <= mid)
{
end++;
}
else
{
count += (end - start - 1 );
start++;
}
}
if (end == n && start < end &&
a[( int )end - 1 ] - a[( int )start] <= mid)
{
long t = end - start - 1 ;
count += (t * (t + 1 ) / 2 );
}
if (count >= need)
return true ;
else
return false ;
}
static long findMedian( int [] a)
{
long n = a.length;
long low = 0 , high = a[( int )n - 1 ] - a[ 0 ];
while (low <= high)
{
long mid = (low + high) / 2 ;
if (possible(mid, a))
high = mid - 1 ;
else
low = mid + 1 ;
}
return high + 1 ;
}
public static void main (String[] args)
{
int [] a = { 1 , 7 , 5 , 2 };
Arrays.sort(a);
System.out.println(findMedian(a));
}
}
|
Python3
def possible(mid, a):
n = len (a);
total = (n * (n - 1 )) / / 2 ;
need = (total + 1 ) / / 2 ;
count = 0 ;
start = 0 ; end = 1 ;
while (end < n):
if (a[end] - a[start] < = mid):
end + = 1 ;
else :
count + = (end - start - 1 );
start + = 1 ;
if (end = = n and start < end and
a[end - 1 ] - a[start] < = mid):
t = end - start - 1 ;
count + = (t * (t + 1 ) / / 2 );
if (count > = need):
return True ;
else :
return False ;
def findMedian(a):
n = len (a);
low = 0 ; high = a[n - 1 ] - a[ 0 ];
while (low < = high):
mid = (low + high) / / 2 ;
if (possible(mid, a)):
high = mid - 1 ;
else :
low = mid + 1 ;
return high + 1 ;
if __name__ = = "__main__" :
a = [ 1 , 7 , 5 , 2 ];
a.sort()
print (findMedian(a));
|
C#
using System;
class GFG{
static bool possible( long mid, int [] a)
{
long n = a.Length;
long total = (n * (n - 1)) / 2;
long need = (total + 1) / 2;
long count = 0;
long start = 0, end = 1;
while (end < n)
{
if (a[( int )end] - a[( int )start] <= mid)
{
end++;
}
else
{
count += (end - start - 1);
start++;
}
}
if (end == n && start < end &&
a[( int )end - 1] - a[( int )start] <= mid)
{
long t = end - start - 1;
count += (t * (t + 1) / 2);
}
if (count >= need)
return true ;
else
return false ;
}
static long findMedian( int [] a)
{
long n = a.Length;
long low = 0, high = a[( int )n - 1] - a[0];
while (low <= high)
{
long mid = (low + high) / 2;
if (possible(mid, a))
high = mid - 1;
else
low = mid + 1;
}
return high + 1;
}
public static void Main ( string [] args)
{
int [] a = { 1, 7, 5, 2 };
Array.Sort(a);
Console.Write(findMedian(a));
}
}
|
Javascript
<script>
function possible(mid, a)
{
let n = a.length;
let total = parseInt((n * (n - 1)) / 2);
let need = parseInt((total + 1) / 2);
let count = 0;
let start = 0, end = 1;
while (end < n) {
if (a[end] - a[start] <= mid) {
end++;
}
else {
count += (end - start - 1);
start++;
}
}
if (end == n && start < end
&& a[end - 1] - a[start] <= mid) {
let t = end - start - 1;
count += parseInt(t * (t + 1) / 2);
}
if (count >= need)
return true ;
else
return false ;
}
function findMedian(a)
{
let n = a.length;
let low = 0, high = a[n - 1] - a[0];
while (low <= high) {
let mid = (low + high) / 2;
if (possible(mid, a))
high = mid - 1;
else
low = mid + 1;
}
return high + 1;
}
let a = [ 1, 7, 5, 2 ];
a.sort();
document.write(findMedian(a));
</script>
|
Output:
3
Time Complexity: O(N*log(M)), where N is the number of elements and M is the maximum difference among pairs of elements of an array.
Auxiliary Space: O(1)