【发布时间】:2016-06-26 02:59:27
【问题描述】:
我正在解决问题find median!
这里基本上我有三个疑问:
- 对于
N == 1 and M is odd的情况
不能直接找MO4( A[0], B[M/2], B[M/2 -1], B[M/2 +1])吗? - 为什么我们将
A和B两个数组都缩短为idxA? - 这个算法的时间复杂度如何
O(logM + logN)。
// A C++ program to
// find median of two sorted arrays of unequal sizes
#include <bits/stdc++.h>
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 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 (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;
}
【问题讨论】:
-
您提供了未注释的代码 - 一般而言,这是一个糟糕的举动。 (您甚至似乎已经手动删除了 cmets。)我更希望在此问题演示中返回值的定义。你放弃了
it is assumed that N is smaller than or equal to M。请编辑您的问题,并特别问 what 使您无法理解:两个/所有数组/范围都可能被仅在一个中找到的值缩短?缩短所有范围确实可以简化问题吗? -
@greybeard 我在编辑时遇到问题。你能检查一下吗?
-
无法回答,因为问题仍处于暂停状态:1.
MO4( A[0], B[M/2], B[M/2 -1], B[M/2 +1])等于MO2(B[M/2], MO3(A[0], B[M/2-1], B[M/2+1]))知道B[M/2]是B的精确中位数,它将始终被选为平均值之一MO4中的术语。 2. 这是遵循分而治之的范式:将问题划分为子问题。在这里,您将两个数组向中位数缩短相等的数量。您不能将两个数组减半,因为它们的大小不同(因此中位数将不再位于范围的中间,即使算法返回错误的值)。 -
我投票决定重新开放,因为这是一个质量很好的有效算法问题。
-
(虽然我认为这是因为错误的原因而被搁置(因此给出了一个无用的参考链接),请访问How do I ask a good question? 并尽可能提出最好的问题。(如@987654323 @ 没有评论这个问题,在
@后面提到他的名字不会让他得到通知。据我所知,编辑会通知,嗯,“审查”)。任何人都可以使用“标志”请求主持人干预链接。)(如果需要拼写,我认为这个问题需要在回答之前进行改进。)