给定两个已排序的数组a []和b [],任务是在O(log n + log m)时间复杂度下(当n是第一个数组中的元素数时)找到这些已排序数组的中位数。 m是第二个数组中的元素数。
这是相等大小问题的两个排序数组的中位数的扩展。在这里,我们也处理大小不等的数组。
例子:
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: m + n为奇数,合并两个数组后获得的数组中位数为第(m + n)/ 2个索引。
- 情况2: m + n是偶数,合并两个数组后获得的数组中位数为索引((m + n)/ 2 – 1)和(m + n)/ 2的元素的平均值
算法:
- 给定两个数组进行排序。因此它们可以在O(m + n)的时间内合并。创建一个变量计数,使输出数组中的元素计数。
- 如果(m + n)的值是奇数,则只有一个中位数,否则中位数是索引为(m + n)/ 2和((m + n)/ 2-1)的元素的平均值。
- 要合并这两个数组,请将两个索引i和j初始分配为0。比较第一个数组的ith索引和第二个数组的jth索引,增加最小元素的索引并增加计数。
- 检查计数是否达到(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
?>
Java
// 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
10
复杂度分析:
- 时间复杂度: O(m + n)。
要合并两个数组,需要O(m + n)时间。 - 空间复杂度: O(1)。
不需要额外的空间。
高效的解决方案:
方法:这个想法很简单,计算两个数组的中位数,并丢弃每个数组的一半。
现在,有一些基本的极端情况。对于小于或等于2的数组
Suppose there are two arrays and the size of both the arrays is greater than 2.
Find the middle element of the first array and middle element of the second array (the first array is smaller than the second) if the middle element of the smaller array is less than the second array, then it can be said that all elements of the first half of smaller array will be in the first half of the output (merged array). So, reduce the search space by ignoring the first half of the smaller array and the second half of the larger array. Else ignore the second half of the smaller array and first half of a larger array.
除此之外,还有其他一些基本情况:
- 如果较小数组的大小为0。返回较大数组的中位数。
- 如果较小数组的大小为1。
- 较大数组的大小也为1。返回两个元素的中值。
- 如果较大数组的大小为奇数。然后,将第二个数组中的元素相加后,它将是偶数,因此中位数将是两个中间元素的平均值。因此,较小数组中的元素只有在位于较大数组中的第(m / 2 – 1)个元素与第(m / 2 + 1)个元素之间时,才会影响中位数。因此,找到较小数组的元素与较大数组的第(m / 2),第(m / 2 – 1)和第(m / 2 + 1)个元素之间的中位数
- 同样,如果大小为偶数,则检查三个元素的中位数,即较小数组的元素和较大数组的第(m / 2),第(m / 2 – 1)个元素
- 如果较小数组的大小为2
- 如果较大的数组也有两个元素,则求四个元素的中位数。
- 如果较大的数组具有奇数个元素,则中位数将是以下3个元素之一
- 较大数组的中间元素
- 较小数组的第一个元素的最大值和正好在中间的元素的最大值,即较大数组中的第M / 2-1个元素
- 较小数组和元素的第二个元素的最小值
就在较大数组中的中间位置之后,即较大数组中的M / 2 + 1个元素
- 如果较大的数组具有偶数个元素,则中位数将是以下4个元素之一
- 较大数组的中间两个元素
- 较小数组的第一个元素的最大值和紧接在较大数组中的第一个中间元素之前的元素的最大值,即M / 2 – 2nd元素
- 较小数组的第二个元素的最小值,以及较大数组中的第二个中间元素之后的元素的最小值,M / 2 + 1个元素
如何将每个数组的一半丢弃?
Let’s take an example to understand this
Input :arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
brr[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19 }
Dry Run of the code:
Recursive call 1:
smaller array[] = 1 2 3 4 5 6 7 8 9 10, mid = 5
larger array[] = 11 12 13 14 15 16 17 18 19 , mid = 15
5 < 15
Discard first half of the first array and second half of the second array
Recursive call 2:
smaller array[] = 11 12 13 14 15, mid = 13
larger array[] = 5 6 7 8 9 10, mid = 7
7 < 13
Discard first half of the second array and second half of the first array
Recursive call 3:
smaller array[] = 11 12 13 , mid = 12
larger array[] = 7 8 9 10 , mid = 8
8 < 12
Discard first half of the second array and second half of the first array
Recursive call 4:
smaller array[] = 11 12
larger array[] = 8 9 10
Size of the smaller array is 2 and the size of the larger array is odd
so, the median will be the median of max( 11, 8), 9, min( 10, 12)
that is 9, 10, 11, so the median is 10.
Output:10.000000
算法:
- 创建一个递归函数,该函数需要两个数组以及两个数组的大小。
- 请注意小于2的数组大小的基本情况。(先前在“方法”中已讨论过)。注意:第一个数组始终是较小的数组。
- 找到两个数组的中间元素。即分别在第一和第二数组的(n – 1)/ 2和(m – 1)/ 2处的元素。比较两个元素。
- 如果较小数组的中间元素小于较大数组的中间元素,则较小数组的前半部分将严格位于合并数组的前半部分。也可以说,较大数组的前半部分和较小数组的后半部分中有一个元素是中位数。因此,将搜索空间减小到较大数组的前半部分和较小数组的后半部分。
- 同样,如果较小数组的中间元素大于较大数组的中间元素,则将搜索空间减小到较小数组的前一半和较大数组的后一半。
执行:
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
?>
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]
执行:
Java
// 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
Median = 3
复杂度分析:
- 时间复杂度:O(n Log n)
- 空间复杂度:O(i + j)。由于我们正在创建大小为i + j的新数组。