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++
// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
#define ll long long
**using**
**namespace**
std;
// Function check if mid can be median
// index of the difference array
**bool**
possible(ll mid, vector<ll>& a)
{
// Size of the array
ll n = a.size();
// Total possible no of pair
// possible
ll total = (n * (n - 1)) / 2;
// The index of the element in the
// differece of all pairs
// from the array
ll need = (total + 1) / 2;
ll count = 0;
ll start = 0, end = 1;
// Count the number of pairs
// having difference <= mid
**while**
(end < n) {
**if**
(a[end] - a[start] <= mid) {
end++;
}
**else**
{
count += (end - start - 1);
start++;
}
}
// If the difference between end
// and first element is less then
// or equal to mid
**if**
(end == n && start < end
&& a[end - 1] - a[start] <= mid) {
ll t = end - start - 1;
count += (t * (t + 1) / 2);
}
// Checking for the no of element less than
// or equal to mid is greater than median or
// not
**if**
(count >= need)
**return**
**true**``;
**else**
**return**
**false**``;
}
// Function to calculate the median
// of differences of all pairs
// from the array
ll findMedian(vector<ll>& a)
{
// Size of the array
ll n = a.size();
// Initialising the low and high
ll low = 0, high = a[n - 1] - a[0];
// Binary search
**while**
(low <= high) {
// Calculate mid
ll mid = (low + high) / 2;
// If mid can be the median
// of the array
**if**
(possible(mid, a))
high = mid - 1;
**else**
low = mid + 1;
}
// Returning the median of the
// differences of pairs from
// the array
**return**
high + 1;
}
// Driver Code
**int**
main()
{
vector<ll> a = { 1, 7, 5, 2 };
sort(a.begin(), a.end());
cout << findMedian(a) << endl;
}
Output:
3
#arrays #mathematical #searching #binary search #frequency-counting #median-finding