📌  相关文章
📜  两个不同大小的排序数组的中位数

📅  最后修改于: 2021-09-16 10:52:40             🧑  作者: Mango

Given two sorted arrays, a[] and b[], the task is to find the median of these sorted arrays, in O(log n + log m) time complexity, when n is the number of elements in the first array, and m is the number of elements in the second array.
This is an extension of median of two sorted arrays of equal size problem. Here we handle arrays of unequal size also. 

例子:

Input: ar1[] = {-5, 3, 6, 12, 15}
        ar2[] = {-12, -10, -6, -3, 4, 10}
Output : The median is 3.
Explanation : The merged array is :
        ar3[] = {-12, -10, -6, -5 , -3,
                 3, 4, 6, 10, 12, 15},
       So the median of the merged array is 3

Input: ar1[] = {2, 3, 5, 8}
        ar2[] = {10, 12, 14, 16, 18, 20}
Output : The median is 11.
Explanation : The merged array is :
        ar3[] = {2, 3, 5, 8, 10, 12, 14, 16, 18, 20}
        if the number of the elements are even, 
        so there are two middle elements,
        take the average between the two :
        (10 + 12) / 2 = 11.

方法 1:此方法使用线性且更简单的方法。

方法:给定的数组已排序,因此以有效的方式合并已排序的数组并保持插入输出数组或打印表单中的元素计数。因此,当输出数组中的元素是给定数组原始大小的一半时,将元素打印为中值元素。有两种情况:

  1. 情况 1: m+n 为奇数,合并两个数组后得到的数组中的中位数位于第 (m+n)/2 个索引处。
  2. 情况 2: m+n 是偶数,中位数将是合并两个数组后得到的数组中索引 ((m+n)/2 – 1) 和 (m+n)/2 处元素的平均值

算法:

  1. 给定两个数组已排序。所以它们可以在 O(m+n) 时间内合并。创建一个变量 count 来计算输出数组中的元素数。
  2. 如果 (m+n) 的值是奇数,则只有一个中位数,否则中位数是索引 (m+n)/2 和 ((m+n)/2 – 1 处元素的平均值)。
  3. 要合并两个数组,保持两个索引 i 和 j 最初分配为 0。比较第一个数组的第 i 个索引和第二个数组的第 j 个索引,增加最小元素的索引并增加计数。
  4. 检查计数是否达到 (m+n) / 2 如果 (m+n) 是奇数并存储元素,如果是偶数则存储 (m+n)/2 th 和 (m+n)/2 -1 th 的平均值元素并打印它。

执行:

C++
// A Simple Merge based O(n) solution to find
// median of two sorted arrays
#include 
using namespace std;
 
/* This function returns median of ar1[] and ar2[].
Assumption in this function:
Both ar1[] and ar2[] are sorted arrays */
int getMedian(int ar1[], int ar2[], int n, int m)
{
    int i = 0; /* Current index of input array ar1[] */
    int j = 0; /* Current index of input array ar2[] */
    int count;
    int m1 = -1, m2 = -1;
 
    // Since there are (n+m) elements,
    // There are following two cases
    // if n+m is odd then the middle
    //index is median i.e. (m+n)/2
    if((m + n) % 2 == 1)
    {
        for (count = 0; count <= (n + m)/2; count++)
        {
            if(i != n && j != m)
            {
                m1 = (ar1[i] > ar2[j]) ? ar2[j++] : ar1[i++];
            }
            else if(i < n)
            {
                m1 = ar1[i++];
            }
            // for case when j ar2[j]) ? ar2[j++] : ar1[i++];
            }
            else if(i < n)
            {
                m1 = ar1[i++];
            }
            // for case when j


C
// A Simple Merge based O(n) solution to find
// median of two sorted arrays
#include 
 
/* This function returns median of ar1[] and ar2[].
Assumption in this function:
Both ar1[] and ar2[] are sorted arrays */
int getMedian(int ar1[], int ar2[], int n, int m)
{
    int i = 0; /* Current index of input array ar1[] */
    int j = 0; /* Current index of input array ar2[] */
    int count;
    int m1 = -1, m2 = -1;
 
    // Since there are (n+m) elements,
    // There are following two cases
    // if n+m is odd then the middle
    //index is median i.e. (m+n)/2
    if((m + n) % 2 == 1) {
        for (count = 0; count <= (n + m)/2; count++) {
            if(i != n && j != m){
            m1 = (ar1[i] > ar2[j]) ? ar2[j++] : ar1[i++];
            }
            else if(i < n){
            m1 = ar1[i++];
            }
            // for case when j ar2[j]) ? ar2[j++] : ar1[i++];
            }
            else if(i < n){
            m1 = ar1[i++];
            }
            // for case when j


Java
// A Simple Merge based O(n) solution
// to find median of two sorted arrays
class GFG{
     
// Function to calculate median
static int getMedian(int ar1[], int ar2[],
                     int n, int m)
{
     
    // Current index of input array ar1[]
    int i = 0;
     
    // Current index of input array ar2[]
    int j = 0;
    int count;
    int m1 = -1, m2 = -1;
     
    // Since there are (n+m) elements, 
    // There are following two cases 
    // if n+m is odd then the middle 
    //index is median i.e. (m+n)/2 
    if ((m + n) % 2 == 1)
    {
        for(count = 0;
            count <= (n + m) / 2;
            count++)
        {
            if (i != n && j != m)
            {
                m1 = (ar1[i] > ar2[j]) ?
                      ar2[j++] : ar1[i++];
            }
            else if (i < n)
            {
                m1 = ar1[i++];
            }
             
            // for case when j ar2[j]) ?
                      ar2[j++] : ar1[i++];
            }
            else if (i < n)
            {
                m1 = ar1[i++];
            }
             
            // for case when j


Python3
# A Simple Merge based O(n) solution to find
# median of two sorted arrays
 
""" This function returns median of ar1[] and ar2[].
Assumption in this function:
Both ar1[] and ar2[] are sorted arrays """
def getMedian(ar1, ar2, n, m) :
 
    i = 0 # Current index of input array ar1[]
    j = 0 # Current index of input array ar2[]
    m1, m2 = -1, -1
 
    # Since there are (n+m) elements,
    # There are following two cases
    # if n+m is odd then the middle
    # index is median i.e. (m+n)/2
    if((m + n) % 2 == 1) :   
        for count in range(((n + m) // 2) + 1) :       
            if(i != n and j != m) :           
                if ar1[i] > ar2[j] :
                    m1 = ar2[j]
                    j += 1
                else :
                    m1 = ar1[i]
                    i += 1           
            elif(i < n) :           
                m1 = ar1[i]
                i += 1
          
            # for case when j ar2[j] :
                    m1 = ar2[j]
                    j += 1
                else :
                    m1 = ar1[i]
                    i += 1           
            elif(i < n) :           
                m1 = ar1[i]
                i += 1
             
            # for case when j


C#
// A Simple Merge based O(n) solution
// to find median of two sorted arrays
using System;
 
class GFG{
     
// Function to calculate median
static int getMedian(int []ar1, int []ar2,
                     int n, int m)
{
     
    // Current index of input array ar1[]
    int i = 0;
     
    // Current index of input array ar2[]
    int j = 0;
     
    int count;
    int m1 = -1, m2 = -1;
     
    // Since there are (n+m) elements, 
    // There are following two cases 
    // if n+m is odd then the middle 
    //index is median i.e. (m+n)/2 
    if ((m + n) % 2 == 1)
    {
        for(count = 0;
            count <= (n + m) / 2;
            count++)
        {
            if (i != n && j != m)
            {
                m1 = (ar1[i] > ar2[j]) ?
                      ar2[j++] : ar1[i++];
            }
            else if (i < n)
            {
                m1 = ar1[i++];
            }
             
            // for case when j ar2[j]) ?
                      ar2[j++] : ar1[i++];
            }
            else if (i < n)
            {
                m1 = ar1[i++];
            }
             
            // for case when j


Javascript


C++
// A C++ program to find median of two sorted arrays of
// unequal sizes
#include 
using namespace std;
 
// A utility function to find median of two integers
float MO2(int a, int b)
{ return ( a + b ) / 2.0; }
 
// A utility function to find median of three integers
float MO3(int a, int b, int c)
{
    return a + b + c - max(a, max(b, c))
                     - min(a, min(b, c));
}
 
// A utility function to find a median of four integers
float MO4(int a, int b, int c, int d)
{
    int Max = max( a, max( b, max( c, d ) ) );
    int Min = min( a, min( b, min( c, d ) ) );
    return ( a + b + c + d - Max - Min ) / 2.0;
}
 
// Utility function to find median of single array
float medianSingle(int arr[], int n)
{
   if (n == 0)
      return -1;
   if (n%2 == 0)
        return (double)(arr[n/2] + arr[n/2-1])/2;
   return arr[n/2];
}
 
// This function assumes that N is smaller than or equal to M
// This function returns -1 if both arrays are empty
float findMedianUtil( int A[], int N, int B[], int M )
{
    // If smaller array is empty, return median from second array
    if (N == 0)
      return medianSingle(B, M);
 
    // If the smaller array has only one element
    if (N == 1)
    {
        // Case 1: If the larger array also has one element,
        // simply call MO2()
        if (M == 1)
            return MO2(A[0], B[0]);
 
        // Case 2: If the larger array has odd number of elements,
        // then consider the middle 3 elements of larger array and
        // the only element of smaller array. Take few examples
        // like following
        // A = {9}, B[] = {5, 8, 10, 20, 30} and
        // A[] = {1}, B[] = {5, 8, 10, 20, 30}
        if (M & 1)
            return MO2( B[M/2], MO3(A[0], B[M/2 - 1], B[M/2 + 1]) );
 
        // Case 3: If the larger array has even number of element,
        // then median will be one of the following 3 elements
        // ... The middle two elements of larger array
        // ... The only element of smaller array
        return MO3( B[M/2], B[M/2 - 1], A[0] );
    }
 
    // If the smaller array has two elements
    else if (N == 2)
    {
        // Case 4: If the larger array also has two elements,
        // simply call MO4()
        if (M == 2)
            return MO4(A[0], A[1], B[0], B[1]);
 
        // Case 5: If the larger array has odd number of elements,
        // then median will be one of the following 3 elements
        // 1. Middle element of larger array
        // 2. Max of first element of smaller array and element
        //    just before the middle in bigger array
        // 3. Min of second element of smaller array and element
        //    just after the middle in bigger array
        if (M & 1)
            return MO3 ( B[M/2],
                         max(A[0], B[M/2 - 1]),
                         min(A[1], B[M/2 + 1])
                       );
 
        // Case 6: If the larger array has even number of elements,
        // then median will be one of the following 4 elements
        // 1) & 2) The middle two elements of larger array
        // 3) Max of first element of smaller array and element
        //    just before the first middle element in bigger array
        // 4. Min of second element of smaller array and element
        //    just after the second middle in bigger array
        return MO4 ( B[M/2],
                     B[M/2 - 1],
                     max( A[0], B[M/2 - 2] ),
                     min( A[1], B[M/2 + 1] )
                   );
    }
 
    int idxA = ( N - 1 ) / 2;
    int idxB = ( M - 1 ) / 2;
 
     /* if A[idxA] <= B[idxB], then median must exist in
        A[idxA....] and B[....idxB] */
    if (A[idxA] <= B[idxB] )
      return findMedianUtil(A + idxA, N/2 + 1, B, M - idxA );
 
    /* if A[idxA] > B[idxB], then median must exist in
       A[...idxA] and B[idxB....] */
    return findMedianUtil(A, N/2 + 1, B + idxA, M - idxA );
}
 
// A wrapper function around findMedianUtil(). This function
// makes sure that smaller array is passed as first argument
// to findMedianUtil
float findMedian( int A[], int N, int B[], int M )
{
    if (N > M)
       return findMedianUtil( B, M, A, N );
 
    return findMedianUtil( A, N, B, M );
}
 
// Driver program to test above functions
int main()
{
    int A[] = {900};
    int B[] = {5, 8, 10, 20};
 
    int N = sizeof(A) / sizeof(A[0]);
    int M = sizeof(B) / sizeof(B[0]);
 
    printf("%f", findMedian( A, N, B, M ) );
    return 0;
}


Java
// A Java program to find median of two sorted arrays of
// unequal sizes
import java.util.*;
 
class GFG {
 
    // A utility function to find median of two integers
    static float MO2(int a, int b) {
        return (float) ((a + b) / 2.0);
    }
 
    // A utility function to find median of three integers
    static float MO3(int a, int b, int c) {
        return a + b + c - Math.max(a, Math.max(b, c)) -
          Math.min(a, Math.min(b, c));
    }
 
    // A utility function to find a median of four integers
    static float MO4(int a, int b, int c, int d) {
        int Max = Math.max(a, Math.max(b, Math.max(c, d)));
        int Min = Math.min(a, Math.min(b, Math.min(c, d)));
        return (float) ((a + b + c + d - Max - Min) / 2.0);
    }
 
    // Utility function to find median of single array
    static float medianSingle(int arr[], int n) {
        if (n == 0)
            return -1;
        if (n % 2 == 0)
            return (float) ((double) (arr[n / 2] +
                                      arr[n / 2 - 1]) / 2);
        return arr[n / 2];
    }
 
    // This function assumes that N is smaller than or equal to M
    // This function returns -1 if both arrays are empty
    static float findMedianUtil(int A[], int N, int B[], int M) {
       
        // If smaller array is empty, return median from second array
        if (N == 0)
            return medianSingle(B, M);
 
        // If the smaller array has only one element
        if (N == 1) {
           
            // Case 1: If the larger array also has one element,
            // simply call MO2()
            if (M == 1)
                return MO2(A[0], B[0]);
 
            // Case 2: If the larger array has odd number of elements,
            // then consider the middle 3 elements of larger array and
            // the only element of smaller array. Take few examples
            // like following
            // A = {9}, B[] = {5, 8, 10, 20, 30} and
            // A[] = {1}, B[] = {5, 8, 10, 20, 30}
            if (M % 2 == 1)
                return MO2(B[M / 2], (int) MO3(A[0],
                            B[M / 2 - 1], B[M / 2 + 1]));
 
            // Case 3: If the larger array has even number of element,
            // then median will be one of the following 3 elements
            // ... The middle two elements of larger array
            // ... The only element of smaller array
            return MO3(B[M / 2], B[M / 2 - 1], A[0]);
        }
 
        // If the smaller array has two elements
        else if (N == 2) {
           
            // Case 4: If the larger array also has two elements,
            // simply call MO4()
            if (M == 2)
                return MO4(A[0], A[1], B[0], B[1]);
 
            // Case 5: If the larger array has odd number of elements,
            // then median will be one of the following 3 elements
            // 1. Middle element of larger array
            // 2. Max of first element of smaller array and element
            // just before the middle in bigger array
            // 3. Min of second element of smaller array and element
            // just after the middle in bigger array
            if (M % 2 == 1)
                return MO3(B[M / 2], Math.max(A[0], B[M / 2 - 1]),
                           Math.min(A[1], B[M / 2 + 1]));
 
            // Case 6: If the larger array has even number of elements,
            // then median will be one of the following 4 elements
            // 1) & 2) The middle two elements of larger array
            // 3) Max of first element of smaller array and element
            // just before the first middle element in bigger array
            // 4. Min of second element of smaller array and element
            // just after the second middle in bigger array
            return MO4(B[M / 2], B[M / 2 - 1],
                       Math.max(A[0], B[M / 2 - 2]),
                       Math.min(A[1], B[M / 2 + 1]));
        }
 
        int idxA = (N - 1) / 2;
        int idxB = (M - 1) / 2;
 
        /*
         * if A[idxA] <= B[idxB], then median
         must exist in A[idxA....] and B[....idxB]
         */
        if (A[idxA] <= B[idxB])
            return findMedianUtil(Arrays.copyOfRange(A, idxA, A.length),
                                  N / 2 + 1, B, M - idxA);
 
        /*
         * if A[idxA] > B[idxB], then median
         must exist in A[...idxA] and B[idxB....]
         */
        return findMedianUtil(A, N / 2 + 1,
               Arrays.copyOfRange(B, idxB, B.length), M - idxA);
    }
 
    // A wrapper function around findMedianUtil(). This function
    // makes sure that smaller array is passed as first argument
    // to findMedianUtil
    static float findMedian(int A[], int N, int B[], int M)
    {
        if (N > M)
            return findMedianUtil(B, M, A, N);
 
        return findMedianUtil(A, N, B, M);
    }
 
    // Driver program to test above functions
    public static void main(String[] args)
    {
        int A[] = { 900 };
        int B[] = { 5, 8, 10, 20 };
 
        int N = A.length;
        int M = B.length;
 
        System.out.printf("%f", findMedian(A, N, B, M));
    }
}
 
// This code is contributed by Princi Singh.


Python3
# A Python3 program to find median of two sorted arrays of
# unequal sizes
 
# A utility function to find median of two integers
def MO2(a, b) :
    return ( a + b ) / 2
 
# A utility function to find median of three integers
def MO3(a, b, c) :
 
    return a + b + c - max(a, max(b, c)) - min(a, min(b, c))
 
# A utility function to find a median of four integers
def MO4(a, b, c, d) :
    Max = max( a, max( b, max( c, d ) ) )
    Min = min( a, min( b, min( c, d ) ) )
    return ( a + b + c + d - Max - Min ) / 2
 
# Utility function to find median of single array
def medianSingle(arr, n) :
    if (n == 0) :
        return -1
    if (n % 2 == 0) :
            return (arr[n / 2] + arr[n / 2 - 1]) / 2
    return arr[n / 2]
 
# This function assumes that N is smaller than or equal to M
# This function returns -1 if both arrays are empty
def findMedianUtil(A, N, B, M) :
 
    # If smaller array is empty, return median from second array
    if (N == 0) :
        return medianSingle(B, M)
 
    # If the smaller array has only one element
    if (N == 1) :
     
        # Case 1: If the larger array also has one element,
        # simply call MO2()
        if (M == 1) :
            return MO2(A[0], B[0])
 
        # Case 2: If the larger array has odd number of elements,
        # then consider the middle 3 elements of larger array and
        # the only element of smaller array. Take few examples
        # like following
        # A = {9}, B[] = {5, 8, 10, 20, 30} and
        # A[] = {1}, B[] = {5, 8, 10, 20, 30}
        if (M & 1 != 0) :
            return MO2( B[M / 2], MO3(A[0], B[M / 2 - 1], B[M / 2 + 1]) )
 
        # Case 3: If the larger array has even number of element,
        # then median will be one of the following 3 elements
        # ... The middle two elements of larger array
        # ... The only element of smaller array
        return MO3(B[M // 2], B[M // 2 - 1], A[0])
 
    # If the smaller array has two elements
    elif (N == 2) :
     
        # Case 4: If the larger array also has two elements,
        # simply call MO4()
        if (M == 2) :
            return MO4(A[0], A[1], B[0], B[1])
 
        # Case 5: If the larger array has odd number of elements,
        # then median will be one of the following 3 elements
        # 1. Middle element of larger array
        # 2. Max of first element of smaller array and element
        # just before the middle in bigger array
        # 3. Min of second element of smaller array and element
        # just after the middle in bigger array
        if (M & 1 != 0) :
            return MO3 (B[M / 2], max(A[0], B[M / 2 - 1]), min(A[1], B[M / 2 + 1]))
 
        # Case 6: If the larger array has even number of elements,
        # then median will be one of the following 4 elements
        # 1) & 2) The middle two elements of larger array
        # 3) Max of first element of smaller array and element
        # just before the first middle element in bigger array
        # 4. Min of second element of smaller array and element
        # just after the second middle in bigger array
        return MO4 (B[M / 2], B[M / 2 - 1], max( A[0], B[M / 2 - 2] ), min( A[1], B[M / 2 + 1] ))
 
    idxA = ( N - 1 ) / 2
    idxB = ( M - 1 ) / 2
 
    ''' if A[idxA] <= B[idxB], then median must exist in
        A[idxA....] and B[....idxB] '''
    if (A[idxA] <= B[idxB] ) :
        return findMedianUtil(A + idxA, N / 2 + 1, B, M - idxA )
 
    ''' if A[idxA] > B[idxB], then median must exist in
    A[...idxA] and B[idxB....] '''
    return findMedianUtil(A, N / 2 + 1, B + idxA, M - idxA )
 
# A wrapper function around findMedianUtil(). This function
# makes sure that smaller array is passed as first argument
# to findMedianUtil
def findMedian(A, N, B, M) :
 
    if (N > M) :
        return findMedianUtil( B, M, A, N );
    return findMedianUtil( A, N, B, M )
 
# Driver code
A = [900]
B = [5, 8, 10, 20]
 
N = len(A)
M = len(B)
 
print(findMedian(A, N, B, M ))
 
# This code is contributed by divyesh072019


C#
// A C# program to find median of two sorted arrays of
// unequal sizes
using System;
class GFG
{
     
    // A utility function to find median of two integers
    static float MO2(int a, int b)
    {
        return (float) ((a + b) / 2.0);
    }
  
    // A utility function to find median of three integers
    static float MO3(int a, int b, int c)
    {
        return a + b + c - Math.Max(a, Math.Max(b, c)) -
          Math.Min(a, Math.Min(b, c));
    }
  
    // A utility function to find a median of four integers
    static float MO4(int a, int b, int c, int d)
    {
        int Max = Math.Max(a, Math.Max(b, Math.Max(c, d)));
        int Min = Math.Min(a, Math.Min(b, Math.Min(c, d)));
        return (float) ((a + b + c + d - Max - Min) / 2.0);
    }
  
    // Utility function to find median of single array
    static float medianSingle(int[] arr, int n)
    {
        if (n == 0)
            return -1;
        if (n % 2 == 0)
            return (float) ((double) (arr[n / 2] +
                                      arr[n / 2 - 1]) / 2);
        return arr[n / 2];
    }
     
    static int[] copyOfRange (int[] src, int start, int end)
    {
        int len = end - start;
        int[] dest = new int[len];
        Array.Copy(src, start, dest, 0, len);
        return dest;
    }
 
    // This function assumes that N is smaller than or equal to M
    // This function returns -1 if both arrays are empty
    static float findMedianUtil(int[] A, int N,
                                int[] B, int M)
    {
        
        // If smaller array is empty,
      // return median from second array
        if (N == 0)
            return medianSingle(B, M);
  
        // If the smaller array has only one element
        if (N == 1)
        {
            
            // Case 1: If the larger array also has one element,
            // simply call MO2()
            if (M == 1)
                return MO2(A[0], B[0]);
  
            // Case 2: If the larger array has odd number of elements,
            // then consider the middle 3 elements of larger array and
            // the only element of smaller array. Take few examples
            // like following
            // A = {9}, B[] = {5, 8, 10, 20, 30} and
            // A[] = {1}, B[] = {5, 8, 10, 20, 30}
            if (M % 2 == 1)
                return MO2(B[M / 2], (int) MO3(A[0],
                            B[M / 2 - 1], B[M / 2 + 1]));
  
            // Case 3: If the larger array has even number of element,
            // then median will be one of the following 3 elements
            // ... The middle two elements of larger array
            // ... The only element of smaller array
            return MO3(B[M / 2], B[M / 2 - 1], A[0]);
        }
  
        // If the smaller array has two elements
        else if (N == 2)
        {
            
            // Case 4: If the larger array also has two elements,
            // simply call MO4()
            if (M == 2)
                return MO4(A[0], A[1], B[0], B[1]);
  
            // Case 5: If the larger array has odd number of elements,
            // then median will be one of the following 3 elements
            // 1. Middle element of larger array
            // 2. Max of first element of smaller array and element
            // just before the middle in bigger array
            // 3. Min of second element of smaller array and element
            // just after the middle in bigger array
            if (M % 2 == 1)
                return MO3(B[M / 2], Math.Max(A[0], B[M / 2 - 1]),
                           Math.Min(A[1], B[M / 2 + 1]));
  
            // Case 6: If the larger array has even number of elements,
            // then median will be one of the following 4 elements
            // 1) & 2) The middle two elements of larger array
            // 3) Max of first element of smaller array and element
            // just before the first middle element in bigger array
            // 4. Min of second element of smaller array and element
            // just after the second middle in bigger array
            return MO4(B[M / 2], B[M / 2 - 1],
                       Math.Max(A[0], B[M / 2 - 2]),
                       Math.Min(A[1], B[M / 2 + 1]));
        }
  
        int idxA = (N - 1) / 2;
        int idxB = (M - 1) / 2;
  
        /*
         * if A[idxA] <= B[idxB], then median
         must exist in A[idxA....] and B[....idxB]
         */
        if (A[idxA] <= B[idxB])
            return findMedianUtil(copyOfRange(A, idxA, A.Length),
                                  N / 2 + 1, B, M - idxA);
        /*
         * if A[idxA] > B[idxB], then median
         must exist in A[...idxA] and B[idxB....]
         */
        return findMedianUtil(A, N / 2 + 1,
                              copyOfRange(B, idxB, B.Length), M - idxA);
    }
  
    // A wrapper function around findMedianUtil(). This function
    // makes sure that smaller array is passed as first argument
    // to findMedianUtil
    static float findMedian(int[] A, int N, int[] B, int M)
    {
        if (N > M)
            return findMedianUtil(B, M, A, N);
  
        return findMedianUtil(A, N, B, M);
    }
   
  // Driver code
  static void Main()
  {
        int[] A = { 900 };
        int[] B = { 5, 8, 10, 20 };
  
        int N = A.Length;
        int M = B.Length;
  
        Console.WriteLine(findMedian(A, N, B, M));
  }
}
 
// This code is contributed by divyeshrabadiya07


PHP
 $B[$idxB],
    then median must exist in
    $A[...$idxA] and $B[$idxB....] */
    return findMedianUtil($A, $N/2 + 1,
                          $B + $idxA, $M - $idxA );
}
 
// A wrapper function around
// findMedianUtil(). This
// function makes sure that
// smaller array is passed as
// first argument to findMedianUtil
function findMedian(&$A, $N,
                    &$B, $M )
{
    if ($N > $M)
    return findMedianUtil($B, $M,
                          $A, $N );
 
    return findMedianUtil($A, $N,
                          $B, $M );
}
 
// Driver Code
$A = array(900);
$B = array(5, 8, 10, 20);
 
$N = sizeof($A);
$M = sizeof($B);
 
echo findMedian( $A, $N, $B, $M );
 
// This code is contributed
// by ChitraNayal
?>


Javascript


C++
// C++ program for the above approach
#include 
using namespace std;
 
int Solution(int arr[], int n)
{
  
    // If length of array is even
     if (n % 2 == 0)
     {
       int z = n / 2;
       int e = arr[z];
       int q = arr[z - 1];
       int ans = (e + q) / 2;
       return ans;
     }
    
     // If length if array is odd
    else
     {
       int z = round(n / 2);
       return arr[z];
     }
}
 
 // Driver Code
int main() {
    
        // TODO Auto-generated method stub
        int arr1[] = { -5, 3, 6, 12, 15 };
        int arr2[] = { -12, -10, -6, -3, 4, 10 };
 
        int i =  sizeof(arr1) / sizeof(arr1[0]);
        int j =  sizeof(arr2) / sizeof(arr2[0]);
 
        int arr3[i+j];
        int l =  i+j;
        // Merge two array into one array
        for(int k=0;kJava
// Java program for the above approach
import java.io.*;
import java.util.Arrays;
 
public class GFG {
    public static int Solution(int[] arr)
    {
        int n = arr.length;
       
        // If length of array is even
        if (n % 2 == 0)
        {
            int z = n / 2;
            int e = arr[z];
            int q = arr[z - 1];
 
            int ans = (e + q) / 2;
            return ans;
        }
       
        // If length if array is odd
        else
        {
            int z = Math.round(n / 2);
            return arr[z];
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
         
        // TODO Auto-generated method stub
        int[] arr1 = { -5, 3, 6, 12, 15 };
        int[] arr2 = { -12, -10, -6, -3, 4, 10 };
 
        int i = arr1.length;
        int j = arr2.length;
 
        int[] arr3 = new int[i + j];
 
        // Merge two array into one array
        System.arraycopy(arr1, 0, arr3, 0, i);
        System.arraycopy(arr2, 0, arr3, i, j);
 
        // Sort the merged array
        Arrays.sort(arr3);
 
        // calling the method
        System.out.print("Median = " + Solution(arr3));
    }
}
// This code is contributed by Manas Tole


Python3
# Python3 program for the above appraoch
def Solution(arr):
 
    n = len(arr)
 
    # If length of array is even
    if n % 2 == 0:
        z = n // 2
        e = arr[z]
        q = arr[z - 1]
        ans = (e + q) / 2
        return ans
         
    # If length of array is odd
    else:
        z = n // 2
        ans = arr[z]
        return ans
 
# Driver code
if __name__ == "__main__":
     
    arr1 = [ -5, 3, 6, 12, 15 ]
    arr2 = [ -12, -10, -6, -3, 4, 10 ]
 
    # Concatenating the two arrays
    arr3 = arr1 + arr2
 
    # Sorting the resultant array
    arr3.sort()
 
    print("Median = ", Solution(arr3))
     
# This code is contributed by kush11


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
    public static int Solution(int[] arr)
    {
        int n = arr.Length;
       
        // If length of array is even
        if (n % 2 == 0)
        {
            int z = n / 2;
            int e = arr[z];
            int q = arr[z - 1];
 
            int ans = (e + q) / 2;
            return ans;
        }
       
        // If length if array is odd
        else
        {
            int z = n / 2;
            return arr[z];
        }
    }
 
    // Driver Code
    static public void Main (){
         
        // TODO Auto-generated method stub
        int[] arr1 = { -5, 3, 6, 12, 15 };
        int[] arr2 = { -12, -10, -6, -3, 4, 10 };
         
        // Merge two array into one array
        var myList = new List();
        myList.AddRange(arr1);
        myList.AddRange(arr2);
        int[] arr3 = myList.ToArray();
 
        // Sort the merged array
        Array.Sort(arr3);
         
        // calling the method
        Console.Write("Median = " + Solution(arr3));
    }
}
 
// This code is contributed by Shubhamsingh10


Javascript


C++
#include 
using namespace std;
// Method to find median
double Median(vector& A, vector& B)
{
    int n = A.size();
    int m = B.size();
    if (n > m)
        return Median(B, A); // Swapping to make A smaller
 
    int start = 0;
    int end = n;
    int realmidinmergedarray = (n + m + 1) / 2;
 
    while (start <= end) {
        int mid = (start + end) / 2;
        int leftAsize = mid;
        int leftBsize = realmidinmergedarray - mid;
        int leftA
            = (leftAsize > 0)
                  ? A[leftAsize - 1]
                  : INT_MIN; // checking overflow of indices
        int leftB
            = (leftBsize > 0) ? B[leftBsize - 1] : INT_MIN;
        int rightA
            = (leftAsize < n) ? A[leftAsize] : INT_MAX;
        int rightB
            = (leftBsize < m) ? B[leftBsize] : INT_MAX;
 
        // if correct partition is done
        if (leftA <= rightB and leftB <= rightA) {
            if ((m + n) % 2 == 0)
                return (max(leftA, leftB)
                        + min(rightA, rightB))
                       / 2.0;
            return max(leftA, leftB);
        }
        else if (leftA > rightB) {
            end = mid - 1;
        }
        else
            start = mid + 1;
    }
    return 0.0;
}
 
int main()
{
    vector arr1 = { -5, 3, 6, 12, 15 };
    vector arr2 = { -12, -10, -6, -3, 4, 10 };
    cout << "Median of the two arrays are" << endl;
    cout << Median(arr1, arr2);
    return 0;
}


输出
10

复杂度分析:

  • 时间复杂度: O(m + n)。
    合并两个数组需要 O(m+n) 时间。
  • 空间复杂度: O(1)。
    不需要额外的空间。

有效的解决方案:

方法:思路很简单,计算两个数组的中位数,丢弃每个数组的一半。
现在,有一些基本的极端情况。对于小于或等于 2 的数组大小

除此之外,还有更多基本的极端情况:

  1. 如果较小数组的大小为 0。返回较大数组的中位数。
  2. 如果较小数组的大小为 1。
    1. 较大数组的大小也是 1。返回两个元素的中值。
    2. 如果较大数组的大小是奇数。然后在添加第二个数组中的元素后,中位数将是两个中间元素的平均值。因此,当且仅当较小数组中的元素位于较大数组的第 (m/2 – 1) 个和第 (m/2 + 1) 个元素之间时,它才会影响中位数。因此,找到四个元素之间的中位数,较小数组的元素和较大数组的第 (m/2) 个、第 (m/2 – 1) 个和第 (m/2 + 1) 个元素
    3. 同样,如果大小为偶数,则检查三个元素的中位数,较小数组的元素和较大数组的第 (m/2) 个,第 (m/2 – 1) 个元素
  3. 如果较小数组的大小为 2
    1. 如果较大的数组也有两个元素,则求四个元素的中位数。
    2. 如果较大的数组具有奇数个元素,则中位数将是以下 3 个元素之一
      1. 较大数组的中间元素
      2. 较小数组的第一个元素和中间元素之前的元素的最大值,即较大数组中的第 M/2-1 个元素
      3. 较小数组和元素的第二个元素的最小值
        就在较大数组的中间之后,即较大数组中的第 M/2 + 1 个元素
    3. 如果较大的数组具有偶数个元素,则中位数将是以下 4 个元素之一
      1. 较大数组的中间两个元素
      2. 较小数组的第一个元素和较大数组中第一个中间元素之前的元素的最大值,即 M/2 – 第二个元素
      3. 较小数组的第二个元素和较大数组中第二个中间元素之后的元素的最小值,M/2 + 第 1 个元素

每个阵列的一半如何被丢弃?

算法:

  1. 创建一个递归函数,它接受两个数组和两个数组的大小。
  2. 注意数组大小小于 2 的基本情况。(之前在方法中讨论过)。注意:第一个数组总是较小的数组。
  3. 找到两个数组的中间元素。即分别位于第一个和第二个数组的 (n – 1)/2 和 (m – 1)/2 处的元素。比较这两个元素。
  4. 如果较小数组的中间元素小于较大数组的中间元素,则较小数组的前半部分必然严格位于合并数组的前半部分。也可以说在较大数组的前半部分和较小数组的后半部分有一个元素是中位数。因此,将搜索空间减少到较大数组的前半部分和较小数组的后半部分。
  5. 类似地,如果较小数组的中间元素大于较大数组的中间元素,则将搜索空间减少到较小数组的前半部分和较大数组的后半部分。

执行:

C++

// A C++ program to find median of two sorted arrays of
// unequal sizes
#include 
using namespace std;
 
// A utility function to find median of two integers
float MO2(int a, int b)
{ return ( a + b ) / 2.0; }
 
// A utility function to find median of three integers
float MO3(int a, int b, int c)
{
    return a + b + c - max(a, max(b, c))
                     - min(a, min(b, c));
}
 
// A utility function to find a median of four integers
float MO4(int a, int b, int c, int d)
{
    int Max = max( a, max( b, max( c, d ) ) );
    int Min = min( a, min( b, min( c, d ) ) );
    return ( a + b + c + d - Max - Min ) / 2.0;
}
 
// Utility function to find median of single array
float medianSingle(int arr[], int n)
{
   if (n == 0)
      return -1;
   if (n%2 == 0)
        return (double)(arr[n/2] + arr[n/2-1])/2;
   return arr[n/2];
}
 
// This function assumes that N is smaller than or equal to M
// This function returns -1 if both arrays are empty
float findMedianUtil( int A[], int N, int B[], int M )
{
    // If smaller array is empty, return median from second array
    if (N == 0)
      return medianSingle(B, M);
 
    // If the smaller array has only one element
    if (N == 1)
    {
        // Case 1: If the larger array also has one element,
        // simply call MO2()
        if (M == 1)
            return MO2(A[0], B[0]);
 
        // Case 2: If the larger array has odd number of elements,
        // then consider the middle 3 elements of larger array and
        // the only element of smaller array. Take few examples
        // like following
        // A = {9}, B[] = {5, 8, 10, 20, 30} and
        // A[] = {1}, B[] = {5, 8, 10, 20, 30}
        if (M & 1)
            return MO2( B[M/2], MO3(A[0], B[M/2 - 1], B[M/2 + 1]) );
 
        // Case 3: If the larger array has even number of element,
        // then median will be one of the following 3 elements
        // ... The middle two elements of larger array
        // ... The only element of smaller array
        return MO3( B[M/2], B[M/2 - 1], A[0] );
    }
 
    // If the smaller array has two elements
    else if (N == 2)
    {
        // Case 4: If the larger array also has two elements,
        // simply call MO4()
        if (M == 2)
            return MO4(A[0], A[1], B[0], B[1]);
 
        // Case 5: If the larger array has odd number of elements,
        // then median will be one of the following 3 elements
        // 1. Middle element of larger array
        // 2. Max of first element of smaller array and element
        //    just before the middle in bigger array
        // 3. Min of second element of smaller array and element
        //    just after the middle in bigger array
        if (M & 1)
            return MO3 ( B[M/2],
                         max(A[0], B[M/2 - 1]),
                         min(A[1], B[M/2 + 1])
                       );
 
        // Case 6: If the larger array has even number of elements,
        // then median will be one of the following 4 elements
        // 1) & 2) The middle two elements of larger array
        // 3) Max of first element of smaller array and element
        //    just before the first middle element in bigger array
        // 4. Min of second element of smaller array and element
        //    just after the second middle in bigger array
        return MO4 ( B[M/2],
                     B[M/2 - 1],
                     max( A[0], B[M/2 - 2] ),
                     min( A[1], B[M/2 + 1] )
                   );
    }
 
    int idxA = ( N - 1 ) / 2;
    int idxB = ( M - 1 ) / 2;
 
     /* if A[idxA] <= B[idxB], then median must exist in
        A[idxA....] and B[....idxB] */
    if (A[idxA] <= B[idxB] )
      return findMedianUtil(A + idxA, N/2 + 1, B, M - idxA );
 
    /* if A[idxA] > B[idxB], then median must exist in
       A[...idxA] and B[idxB....] */
    return findMedianUtil(A, N/2 + 1, B + idxA, M - idxA );
}
 
// A wrapper function around findMedianUtil(). This function
// makes sure that smaller array is passed as first argument
// to findMedianUtil
float findMedian( int A[], int N, int B[], int M )
{
    if (N > M)
       return findMedianUtil( B, M, A, N );
 
    return findMedianUtil( A, N, B, M );
}
 
// Driver program to test above functions
int main()
{
    int A[] = {900};
    int B[] = {5, 8, 10, 20};
 
    int N = sizeof(A) / sizeof(A[0]);
    int M = sizeof(B) / sizeof(B[0]);
 
    printf("%f", findMedian( A, N, B, M ) );
    return 0;
}

Java

// A Java program to find median of two sorted arrays of
// unequal sizes
import java.util.*;
 
class GFG {
 
    // A utility function to find median of two integers
    static float MO2(int a, int b) {
        return (float) ((a + b) / 2.0);
    }
 
    // A utility function to find median of three integers
    static float MO3(int a, int b, int c) {
        return a + b + c - Math.max(a, Math.max(b, c)) -
          Math.min(a, Math.min(b, c));
    }
 
    // A utility function to find a median of four integers
    static float MO4(int a, int b, int c, int d) {
        int Max = Math.max(a, Math.max(b, Math.max(c, d)));
        int Min = Math.min(a, Math.min(b, Math.min(c, d)));
        return (float) ((a + b + c + d - Max - Min) / 2.0);
    }
 
    // Utility function to find median of single array
    static float medianSingle(int arr[], int n) {
        if (n == 0)
            return -1;
        if (n % 2 == 0)
            return (float) ((double) (arr[n / 2] +
                                      arr[n / 2 - 1]) / 2);
        return arr[n / 2];
    }
 
    // This function assumes that N is smaller than or equal to M
    // This function returns -1 if both arrays are empty
    static float findMedianUtil(int A[], int N, int B[], int M) {
       
        // If smaller array is empty, return median from second array
        if (N == 0)
            return medianSingle(B, M);
 
        // If the smaller array has only one element
        if (N == 1) {
           
            // Case 1: If the larger array also has one element,
            // simply call MO2()
            if (M == 1)
                return MO2(A[0], B[0]);
 
            // Case 2: If the larger array has odd number of elements,
            // then consider the middle 3 elements of larger array and
            // the only element of smaller array. Take few examples
            // like following
            // A = {9}, B[] = {5, 8, 10, 20, 30} and
            // A[] = {1}, B[] = {5, 8, 10, 20, 30}
            if (M % 2 == 1)
                return MO2(B[M / 2], (int) MO3(A[0],
                            B[M / 2 - 1], B[M / 2 + 1]));
 
            // Case 3: If the larger array has even number of element,
            // then median will be one of the following 3 elements
            // ... The middle two elements of larger array
            // ... The only element of smaller array
            return MO3(B[M / 2], B[M / 2 - 1], A[0]);
        }
 
        // If the smaller array has two elements
        else if (N == 2) {
           
            // Case 4: If the larger array also has two elements,
            // simply call MO4()
            if (M == 2)
                return MO4(A[0], A[1], B[0], B[1]);
 
            // Case 5: If the larger array has odd number of elements,
            // then median will be one of the following 3 elements
            // 1. Middle element of larger array
            // 2. Max of first element of smaller array and element
            // just before the middle in bigger array
            // 3. Min of second element of smaller array and element
            // just after the middle in bigger array
            if (M % 2 == 1)
                return MO3(B[M / 2], Math.max(A[0], B[M / 2 - 1]),
                           Math.min(A[1], B[M / 2 + 1]));
 
            // Case 6: If the larger array has even number of elements,
            // then median will be one of the following 4 elements
            // 1) & 2) The middle two elements of larger array
            // 3) Max of first element of smaller array and element
            // just before the first middle element in bigger array
            // 4. Min of second element of smaller array and element
            // just after the second middle in bigger array
            return MO4(B[M / 2], B[M / 2 - 1],
                       Math.max(A[0], B[M / 2 - 2]),
                       Math.min(A[1], B[M / 2 + 1]));
        }
 
        int idxA = (N - 1) / 2;
        int idxB = (M - 1) / 2;
 
        /*
         * if A[idxA] <= B[idxB], then median
         must exist in A[idxA....] and B[....idxB]
         */
        if (A[idxA] <= B[idxB])
            return findMedianUtil(Arrays.copyOfRange(A, idxA, A.length),
                                  N / 2 + 1, B, M - idxA);
 
        /*
         * if A[idxA] > B[idxB], then median
         must exist in A[...idxA] and B[idxB....]
         */
        return findMedianUtil(A, N / 2 + 1,
               Arrays.copyOfRange(B, idxB, B.length), M - idxA);
    }
 
    // A wrapper function around findMedianUtil(). This function
    // makes sure that smaller array is passed as first argument
    // to findMedianUtil
    static float findMedian(int A[], int N, int B[], int M)
    {
        if (N > M)
            return findMedianUtil(B, M, A, N);
 
        return findMedianUtil(A, N, B, M);
    }
 
    // Driver program to test above functions
    public static void main(String[] args)
    {
        int A[] = { 900 };
        int B[] = { 5, 8, 10, 20 };
 
        int N = A.length;
        int M = B.length;
 
        System.out.printf("%f", findMedian(A, N, B, M));
    }
}
 
// This code is contributed by Princi Singh.

蟒蛇3

# A Python3 program to find median of two sorted arrays of
# unequal sizes
 
# A utility function to find median of two integers
def MO2(a, b) :
    return ( a + b ) / 2
 
# A utility function to find median of three integers
def MO3(a, b, c) :
 
    return a + b + c - max(a, max(b, c)) - min(a, min(b, c))
 
# A utility function to find a median of four integers
def MO4(a, b, c, d) :
    Max = max( a, max( b, max( c, d ) ) )
    Min = min( a, min( b, min( c, d ) ) )
    return ( a + b + c + d - Max - Min ) / 2
 
# Utility function to find median of single array
def medianSingle(arr, n) :
    if (n == 0) :
        return -1
    if (n % 2 == 0) :
            return (arr[n / 2] + arr[n / 2 - 1]) / 2
    return arr[n / 2]
 
# This function assumes that N is smaller than or equal to M
# This function returns -1 if both arrays are empty
def findMedianUtil(A, N, B, M) :
 
    # If smaller array is empty, return median from second array
    if (N == 0) :
        return medianSingle(B, M)
 
    # If the smaller array has only one element
    if (N == 1) :
     
        # Case 1: If the larger array also has one element,
        # simply call MO2()
        if (M == 1) :
            return MO2(A[0], B[0])
 
        # Case 2: If the larger array has odd number of elements,
        # then consider the middle 3 elements of larger array and
        # the only element of smaller array. Take few examples
        # like following
        # A = {9}, B[] = {5, 8, 10, 20, 30} and
        # A[] = {1}, B[] = {5, 8, 10, 20, 30}
        if (M & 1 != 0) :
            return MO2( B[M / 2], MO3(A[0], B[M / 2 - 1], B[M / 2 + 1]) )
 
        # Case 3: If the larger array has even number of element,
        # then median will be one of the following 3 elements
        # ... The middle two elements of larger array
        # ... The only element of smaller array
        return MO3(B[M // 2], B[M // 2 - 1], A[0])
 
    # If the smaller array has two elements
    elif (N == 2) :
     
        # Case 4: If the larger array also has two elements,
        # simply call MO4()
        if (M == 2) :
            return MO4(A[0], A[1], B[0], B[1])
 
        # Case 5: If the larger array has odd number of elements,
        # then median will be one of the following 3 elements
        # 1. Middle element of larger array
        # 2. Max of first element of smaller array and element
        # just before the middle in bigger array
        # 3. Min of second element of smaller array and element
        # just after the middle in bigger array
        if (M & 1 != 0) :
            return MO3 (B[M / 2], max(A[0], B[M / 2 - 1]), min(A[1], B[M / 2 + 1]))
 
        # Case 6: If the larger array has even number of elements,
        # then median will be one of the following 4 elements
        # 1) & 2) The middle two elements of larger array
        # 3) Max of first element of smaller array and element
        # just before the first middle element in bigger array
        # 4. Min of second element of smaller array and element
        # just after the second middle in bigger array
        return MO4 (B[M / 2], B[M / 2 - 1], max( A[0], B[M / 2 - 2] ), min( A[1], B[M / 2 + 1] ))
 
    idxA = ( N - 1 ) / 2
    idxB = ( M - 1 ) / 2
 
    ''' if A[idxA] <= B[idxB], then median must exist in
        A[idxA....] and B[....idxB] '''
    if (A[idxA] <= B[idxB] ) :
        return findMedianUtil(A + idxA, N / 2 + 1, B, M - idxA )
 
    ''' if A[idxA] > B[idxB], then median must exist in
    A[...idxA] and B[idxB....] '''
    return findMedianUtil(A, N / 2 + 1, B + idxA, M - idxA )
 
# A wrapper function around findMedianUtil(). This function
# makes sure that smaller array is passed as first argument
# to findMedianUtil
def findMedian(A, N, B, M) :
 
    if (N > M) :
        return findMedianUtil( B, M, A, N );
    return findMedianUtil( A, N, B, M )
 
# Driver code
A = [900]
B = [5, 8, 10, 20]
 
N = len(A)
M = len(B)
 
print(findMedian(A, N, B, M ))
 
# This code is contributed by divyesh072019

C#

// A C# program to find median of two sorted arrays of
// unequal sizes
using System;
class GFG
{
     
    // A utility function to find median of two integers
    static float MO2(int a, int b)
    {
        return (float) ((a + b) / 2.0);
    }
  
    // A utility function to find median of three integers
    static float MO3(int a, int b, int c)
    {
        return a + b + c - Math.Max(a, Math.Max(b, c)) -
          Math.Min(a, Math.Min(b, c));
    }
  
    // A utility function to find a median of four integers
    static float MO4(int a, int b, int c, int d)
    {
        int Max = Math.Max(a, Math.Max(b, Math.Max(c, d)));
        int Min = Math.Min(a, Math.Min(b, Math.Min(c, d)));
        return (float) ((a + b + c + d - Max - Min) / 2.0);
    }
  
    // Utility function to find median of single array
    static float medianSingle(int[] arr, int n)
    {
        if (n == 0)
            return -1;
        if (n % 2 == 0)
            return (float) ((double) (arr[n / 2] +
                                      arr[n / 2 - 1]) / 2);
        return arr[n / 2];
    }
     
    static int[] copyOfRange (int[] src, int start, int end)
    {
        int len = end - start;
        int[] dest = new int[len];
        Array.Copy(src, start, dest, 0, len);
        return dest;
    }
 
    // This function assumes that N is smaller than or equal to M
    // This function returns -1 if both arrays are empty
    static float findMedianUtil(int[] A, int N,
                                int[] B, int M)
    {
        
        // If smaller array is empty,
      // return median from second array
        if (N == 0)
            return medianSingle(B, M);
  
        // If the smaller array has only one element
        if (N == 1)
        {
            
            // Case 1: If the larger array also has one element,
            // simply call MO2()
            if (M == 1)
                return MO2(A[0], B[0]);
  
            // Case 2: If the larger array has odd number of elements,
            // then consider the middle 3 elements of larger array and
            // the only element of smaller array. Take few examples
            // like following
            // A = {9}, B[] = {5, 8, 10, 20, 30} and
            // A[] = {1}, B[] = {5, 8, 10, 20, 30}
            if (M % 2 == 1)
                return MO2(B[M / 2], (int) MO3(A[0],
                            B[M / 2 - 1], B[M / 2 + 1]));
  
            // Case 3: If the larger array has even number of element,
            // then median will be one of the following 3 elements
            // ... The middle two elements of larger array
            // ... The only element of smaller array
            return MO3(B[M / 2], B[M / 2 - 1], A[0]);
        }
  
        // If the smaller array has two elements
        else if (N == 2)
        {
            
            // Case 4: If the larger array also has two elements,
            // simply call MO4()
            if (M == 2)
                return MO4(A[0], A[1], B[0], B[1]);
  
            // Case 5: If the larger array has odd number of elements,
            // then median will be one of the following 3 elements
            // 1. Middle element of larger array
            // 2. Max of first element of smaller array and element
            // just before the middle in bigger array
            // 3. Min of second element of smaller array and element
            // just after the middle in bigger array
            if (M % 2 == 1)
                return MO3(B[M / 2], Math.Max(A[0], B[M / 2 - 1]),
                           Math.Min(A[1], B[M / 2 + 1]));
  
            // Case 6: If the larger array has even number of elements,
            // then median will be one of the following 4 elements
            // 1) & 2) The middle two elements of larger array
            // 3) Max of first element of smaller array and element
            // just before the first middle element in bigger array
            // 4. Min of second element of smaller array and element
            // just after the second middle in bigger array
            return MO4(B[M / 2], B[M / 2 - 1],
                       Math.Max(A[0], B[M / 2 - 2]),
                       Math.Min(A[1], B[M / 2 + 1]));
        }
  
        int idxA = (N - 1) / 2;
        int idxB = (M - 1) / 2;
  
        /*
         * if A[idxA] <= B[idxB], then median
         must exist in A[idxA....] and B[....idxB]
         */
        if (A[idxA] <= B[idxB])
            return findMedianUtil(copyOfRange(A, idxA, A.Length),
                                  N / 2 + 1, B, M - idxA);
        /*
         * if A[idxA] > B[idxB], then median
         must exist in A[...idxA] and B[idxB....]
         */
        return findMedianUtil(A, N / 2 + 1,
                              copyOfRange(B, idxB, B.Length), M - idxA);
    }
  
    // A wrapper function around findMedianUtil(). This function
    // makes sure that smaller array is passed as first argument
    // to findMedianUtil
    static float findMedian(int[] A, int N, int[] B, int M)
    {
        if (N > M)
            return findMedianUtil(B, M, A, N);
  
        return findMedianUtil(A, N, B, M);
    }
   
  // Driver code
  static void Main()
  {
        int[] A = { 900 };
        int[] B = { 5, 8, 10, 20 };
  
        int N = A.Length;
        int M = B.Length;
  
        Console.WriteLine(findMedian(A, N, B, M));
  }
}
 
// This code is contributed by divyeshrabadiya07

PHP

 $B[$idxB],
    then median must exist in
    $A[...$idxA] and $B[$idxB....] */
    return findMedianUtil($A, $N/2 + 1,
                          $B + $idxA, $M - $idxA );
}
 
// A wrapper function around
// findMedianUtil(). This
// function makes sure that
// smaller array is passed as
// first argument to findMedianUtil
function findMedian(&$A, $N,
                    &$B, $M )
{
    if ($N > $M)
    return findMedianUtil($B, $M,
                          $A, $N );
 
    return findMedianUtil($A, $N,
                          $B, $M );
}
 
// Driver Code
$A = array(900);
$B = array(5, 8, 10, 20);
 
$N = sizeof($A);
$M = sizeof($B);
 
echo findMedian( $A, $N, $B, $M );
 
// This code is contributed
// by ChitraNayal
?>

Javascript


输出
10.000000

复杂度分析:

  • 时间复杂度: O(min(log m, log n))。
    在每一步中,每个数组的一半被丢弃。因此该算法需要 O(min(log m, log n)) 时间才能达到中值。
  • 空间复杂度: O(1)。
    不需要额外的空间。

解决方案 3:简单的数学方法

方法:给定的两个数组已经排序,所以我们需要使用 System.arraycopy(src, srcPos, dest, destPos, length) 方法将它们合并到第三个数组中,然后使用 Arrays.sort(array) 方法对第三个数组进行排序.

1.案例1:如果第三个数组的长度是奇数,那么中位数在合并两个数组后得到的数组中的(长度)/第2个索引处。

2. 情况2:如果第三个数组的长度是偶数,那么中位数就是合并后得到的数组中索引((length)/2)和((length)/2 – 1)处元素的平均值数组。

算法:

1. Merge the two given arrays into one array.
2. Then sort the third(merged) array
3. If the length of the third array is even then :
    divide the length of array by 2
    return arr[value]  + arr[value - 1] / 2
    
4. If the length of the third array is odd then :
    divide the length of array by 2
    round that value 
    return the arr[value] 

执行:

C++

// C++ program for the above approach
#include 
using namespace std;
 
int Solution(int arr[], int n)
{
  
    // If length of array is even
     if (n % 2 == 0)
     {
       int z = n / 2;
       int e = arr[z];
       int q = arr[z - 1];
       int ans = (e + q) / 2;
       return ans;
     }
    
     // If length if array is odd
    else
     {
       int z = round(n / 2);
       return arr[z];
     }
}
 
 // Driver Code
int main() {
    
        // TODO Auto-generated method stub
        int arr1[] = { -5, 3, 6, 12, 15 };
        int arr2[] = { -12, -10, -6, -3, 4, 10 };
 
        int i =  sizeof(arr1) / sizeof(arr1[0]);
        int j =  sizeof(arr2) / sizeof(arr2[0]);
 
        int arr3[i+j];
        int l =  i+j;
        // Merge two array into one array
        for(int k=0;kJava
// Java program for the above approach
import java.io.*;
import java.util.Arrays;
 
public class GFG {
    public static int Solution(int[] arr)
    {
        int n = arr.length;
       
        // If length of array is even
        if (n % 2 == 0)
        {
            int z = n / 2;
            int e = arr[z];
            int q = arr[z - 1];
 
            int ans = (e + q) / 2;
            return ans;
        }
       
        // If length if array is odd
        else
        {
            int z = Math.round(n / 2);
            return arr[z];
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
         
        // TODO Auto-generated method stub
        int[] arr1 = { -5, 3, 6, 12, 15 };
        int[] arr2 = { -12, -10, -6, -3, 4, 10 };
 
        int i = arr1.length;
        int j = arr2.length;
 
        int[] arr3 = new int[i + j];
 
        // Merge two array into one array
        System.arraycopy(arr1, 0, arr3, 0, i);
        System.arraycopy(arr2, 0, arr3, i, j);
 
        // Sort the merged array
        Arrays.sort(arr3);
 
        // calling the method
        System.out.print("Median = " + Solution(arr3));
    }
}
// This code is contributed by Manas Tole

蟒蛇3

# Python3 program for the above appraoch
def Solution(arr):
 
    n = len(arr)
 
    # If length of array is even
    if n % 2 == 0:
        z = n // 2
        e = arr[z]
        q = arr[z - 1]
        ans = (e + q) / 2
        return ans
         
    # If length of array is odd
    else:
        z = n // 2
        ans = arr[z]
        return ans
 
# Driver code
if __name__ == "__main__":
     
    arr1 = [ -5, 3, 6, 12, 15 ]
    arr2 = [ -12, -10, -6, -3, 4, 10 ]
 
    # Concatenating the two arrays
    arr3 = arr1 + arr2
 
    # Sorting the resultant array
    arr3.sort()
 
    print("Median = ", Solution(arr3))
     
# This code is contributed by kush11

C#

// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
    public static int Solution(int[] arr)
    {
        int n = arr.Length;
       
        // If length of array is even
        if (n % 2 == 0)
        {
            int z = n / 2;
            int e = arr[z];
            int q = arr[z - 1];
 
            int ans = (e + q) / 2;
            return ans;
        }
       
        // If length if array is odd
        else
        {
            int z = n / 2;
            return arr[z];
        }
    }
 
    // Driver Code
    static public void Main (){
         
        // TODO Auto-generated method stub
        int[] arr1 = { -5, 3, 6, 12, 15 };
        int[] arr2 = { -12, -10, -6, -3, 4, 10 };
         
        // Merge two array into one array
        var myList = new List();
        myList.AddRange(arr1);
        myList.AddRange(arr2);
        int[] arr3 = myList.ToArray();
 
        // Sort the merged array
        Array.Sort(arr3);
         
        // calling the method
        Console.Write("Median = " + Solution(arr3));
    }
}
 
// This code is contributed by Shubhamsingh10

Javascript


输出
Median = 3

复杂性分析

  • 时间复杂度:O(n Log n)
  • 空间复杂度:O(i+j)。因为我们正在创建一个大小为 i+j 的新数组。

解决方案 4 :二分搜索

方法:给定的两个数组进行排序,因此我们可以利用二分查找的能力来划分数组并找到中位数。

中位数是指整个数组被分成两部分的点。因此,由于两个数组没有合并,所以为了得到中位数,我们需要合并,这是代价高昂的。因此,我们将使用下面给定的算法来有效地找到中位数,而不是合并。

算法:

1. Lets assume that there are two arrays A and B with array A having the minimum number of elements.
   If this is not the case than swap A and B to make A having small size.
2. The edge cases like one array is empty or both are empty will be handled.
3. let n be the size of A and m be the size of B.
   Now think of an idea that if we have to find the median than we have to divide the whole merged array into two parts
   namely left and right parts.
   Now since we are given the size of left part (i.e (n+m+1)/2), Now look at below given example.
   
       A-> 1,2,3,4,5     n = 5
       B-> 1,2,3,4,5,6   m = 6
   
    Here merged array will look like :- 1,1,2,2,3,3,4,4,5,5,6 and median then is 3
    
    Now we can see our left part which is underlined. We divide A and B into two parts such that the 
    sum of left part of both A and B will result in left part of merged array.
    
    A-> 1,2,3,4,5     // pointers l =0 and r = n-1 hence mid = (l+r)/2;
       B -> 1,2,3,4,5,6

    we can see that left part of A is given as n/2 and since total length of left part in merged array
    is (m+n+1)/2, so left part of B = (m+n+1)/2-n/2;
    
    Now we just have to confirm if our left and right partitions in A and B are correct or not.
    
4. Now we have 4 variables indicating four values two from array A and two from array B.
    leftA -> Rightmost element in left part of A = 2
    leftb -> Rightmost element in left part of B = 4
    rightA -> Leftmost element in right part of A = 3
    rightB -> Leftmost element in right part of B = 5
    
    Hence to confirm that partition is correct we have to check the following conditions.
    leftA<=rightB and leftB<=rightA  // This is the case when the sum of two parts of A and B results in left part of merged array
    
    if our partition not works that means we have to  find other mid point in A and then left part in B
    This is seen when
     
    leftA > rightB    //means we have to dec size of A's partition
    so do r = mid-1;
    else
        do l =mid+1;
    
    Hence repeat the above steps with new partitions till we get the answers.
5. If leftA<=rightB and leftB<=rightA
    then we get correct partition and our answer depends on the total size of merged array (i.e. m+n)
    
    If (m+n)%2==0
     ans is max(leftA,leftB)+min(rightA,rightB)/2; // max of left part is nearest to median and min of right part is nearest to medain
    else
     ans is max(leftA,leftB);

因此上述算法可以编码为

C++

#include 
using namespace std;
// Method to find median
double Median(vector& A, vector& B)
{
    int n = A.size();
    int m = B.size();
    if (n > m)
        return Median(B, A); // Swapping to make A smaller
 
    int start = 0;
    int end = n;
    int realmidinmergedarray = (n + m + 1) / 2;
 
    while (start <= end) {
        int mid = (start + end) / 2;
        int leftAsize = mid;
        int leftBsize = realmidinmergedarray - mid;
        int leftA
            = (leftAsize > 0)
                  ? A[leftAsize - 1]
                  : INT_MIN; // checking overflow of indices
        int leftB
            = (leftBsize > 0) ? B[leftBsize - 1] : INT_MIN;
        int rightA
            = (leftAsize < n) ? A[leftAsize] : INT_MAX;
        int rightB
            = (leftBsize < m) ? B[leftBsize] : INT_MAX;
 
        // if correct partition is done
        if (leftA <= rightB and leftB <= rightA) {
            if ((m + n) % 2 == 0)
                return (max(leftA, leftB)
                        + min(rightA, rightB))
                       / 2.0;
            return max(leftA, leftB);
        }
        else if (leftA > rightB) {
            end = mid - 1;
        }
        else
            start = mid + 1;
    }
    return 0.0;
}
 
int main()
{
    vector arr1 = { -5, 3, 6, 12, 15 };
    vector arr2 = { -12, -10, -6, -3, 4, 10 };
    cout << "Median of the two arrays are" << endl;
    cout << Median(arr1, arr2);
    return 0;
}
输出
Median of the two arrays are
3

时间复杂度: O(log(m+n))
辅助空间: O(1)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程