📜  数组中所有对的差的中位数

📅  最后修改于: 2021-04-23 16:03:25             🧑  作者: Mango

给定长度为N的数组arr [] ,任务是找到所有数组元素对的差的中值。

例子:

天真的方法:任务是从给定的数组中生成所有可能的对,并计算arr []数组中每对的差并将它们存储在diff []数组中。排序diff []并找到中间元素。

时间复杂度: O(N 2 * log(N 2 ))
辅助空间: O(N 2 )

高效的方法:可以使用二进制搜索和排序来优化上述方法。请按照以下步骤解决问题:

  • 对给定的数组进行排序。
  • 初始化low = 0high = arr [N-1] -arr [0]
  • 计算中间等于(低+高)/ 2。
  • 计算小于中点的差数。如果超过差值阵列的中值化指数,[小区(N *(N – 1)/ 2)],然后更新高达中间- 1。否则,将低位更新为mid +1
  • 重复上述步骤,直到相等。

下面是上述方法的实现:

C++
// C++ Program to implement 
// the above approach 
#include  
#define ll long long 
using namespace std; 
  
// Function check if mid can be median 
// index of the difference array 
bool possible(ll mid, vector& 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& 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 a = { 1, 7, 5, 2 }; 
  
    sort(a.begin(), a.end()); 
  
    cout << findMedian(a) << endl; 
}


Java
// Java program to implement 
// the above approach 
import java.util.*;
  
class GFG{
  
// Function check if mid can be median 
// index of the difference array 
static boolean possible(long mid, int[] a) 
{ 
  
    // Size of the array 
    long n = a.length; 
  
    // Total possible no of pair 
    // possible 
    long total = (n * (n - 1)) / 2; 
  
    // The index of the element in the 
    // differece of all pairs 
    // from the array 
    long need = (total + 1) / 2; 
  
    long count = 0; 
    long start = 0, end = 1; 
  
    // Count the number of pairs 
    // having difference <= mid 
    while (end < n)
    { 
        if (a[(int)end] - a[(int)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[(int)end - 1] - a[(int)start] <= mid) 
    { 
        long 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 
static long findMedian(int[] a) 
{ 
  
    // Size of the array 
    long n = a.length; 
  
    // Initialising the low and high 
    long low = 0, high = a[(int)n - 1] - a[0]; 
  
    // Binary search 
    while (low <= high)
    { 
  
        // Calculate mid 
        long 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
public static void main (String[] args)
{
    int[] a = { 1, 7, 5, 2 }; 
      
    Arrays.sort(a); 
      
    System.out.println(findMedian(a));
}
}
  
// This code is contributed by offbeat


Python3
# Python3 program to implement 
# the above approach 
  
# Function check if mid can be median 
# index of the difference array 
def possible(mid, a): 
  
    # Size of the array 
    n = len(a); 
  
    # Total possible no of pair 
    # possible 
    total = (n * (n - 1)) // 2; 
  
    # The index of the element in the 
    # differece of all pairs 
    # from the array 
    need = (total + 1) // 2; 
  
    count = 0; 
    start = 0; end = 1; 
  
    # Count the number of pairs 
    # having difference <= mid 
    while (end < n):
        if (a[end] - a[start] <= mid):
            end += 1; 
          
        else:
            count += (end - start - 1); 
            start += 1; 
  
    # If the difference between end 
    # and first element is less then 
    # or equal to mid 
    if (end == n and start < end and 
      a[end - 1] - a[start] <= mid):
        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 
def findMedian(a): 
  
    # Size of the array 
    n = len(a); 
  
    # Initialising the low and high 
    low = 0; high = a[n - 1] - a[0]; 
  
    # Binary search 
    while (low <= high):
  
        # Calculate mid 
        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 
if __name__ == "__main__" : 
  
    a = [ 1, 7, 5, 2 ]; 
      
    a.sort()
      
    print(findMedian(a));
      
# This code is contributed by AnkitRai01


C#
// C# program to implement 
// the above approach 
using System;
  
class GFG{
  
// Function check if mid can be median 
// index of the difference array 
static bool possible(long mid, int[] a) 
{ 
  
    // Size of the array 
    long n = a.Length; 
  
    // Total possible no of pair 
    // possible 
    long total = (n * (n - 1)) / 2; 
  
    // The index of the element in the 
    // differece of all pairs 
    // from the array 
    long need = (total + 1) / 2; 
  
    long count = 0; 
    long start = 0, end = 1; 
  
    // Count the number of pairs 
    // having difference <= mid 
    while (end < n)
    { 
        if (a[(int)end] - a[(int)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[(int)end - 1] - a[(int)start] <= mid) 
    { 
        long 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 
static long findMedian(int[] a) 
{ 
  
    // Size of the array 
    long n = a.Length; 
  
    // Initialising the low and high 
    long low = 0, high = a[(int)n - 1] - a[0]; 
  
    // Binary search 
    while (low <= high)
    { 
  
        // Calculate mid 
        long 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
public static void Main (string[] args)
{
    int[] a = { 1, 7, 5, 2 }; 
      
    Array.Sort(a); 
      
    Console.Write(findMedian(a));
}
}
  
// This code is contributed by rutvik_56


输出:

3

时间复杂度: O(N * log(M)),其中N是元素数,M是数组元素对之间的最大差。
辅助空间: O(1)