求两个排序数组中位数,这道题是很有意思的一道题目,算法导论中9.3-8题,这题必须在O(logn)的时间复杂度求解,否则肯定悲剧。。。
这题有个关键的条件,那就是这两个数组长度相等
思路如下:
数组A:1, 3, 5, 7, 9
数组B:2, 4, 6, 8, 10
首先取二者的中位数,在O(1)时间复杂度内求出,那么数组A的midValue = 5,数组B的midValue = 6,则较小的元素midValue的左边所有元素,也就是midPosition个,和较大元素右边的所有元素,都要去掉,由于去掉的元素占所有元素的一半,所以复杂度为O(logn)。只需要移动begin和end的position即可。
第一轮:
数组A:1, 3, 5, 7, 9
数组B:2, 4, 6, 8, 10
第二轮:
数组A:1, 3, 5, 7, 9
数组B:2, 4, 6, 8, 10
只剩下两个元素,由于这种情形下midValue始终是偏左的元素,因此循环无法退出,所以满足lhsBegin == lhsEnd - 1和 rhsBegin == rhsEnd - 1时,循环退出!
如果两个
上述情形是当数组中有两个及以上元素才成立,必须考虑两个数组只存在一个元素的情形,那么直接取较小的元素即可!
#include <iostream>
using namespace std;
int findMidValue(int *lhs, int *rhs, int size)
{
if (lhs == NULL || rhs == NULL || size <= 0)
return -1;
int lhsBegin = 0;
int rhsBegin = 0;
int lhsEnd = size - 1;
int rhsEnd = size - 1;
int result;
while ((lhsBegin < lhsEnd && rhsBegin < rhsEnd))
{
if ((lhsBegin == lhsEnd - 1 && rhsBegin == rhsEnd - 1))
break;
int lhsMid = (lhsBegin + lhsEnd) >> 1;
int rhsMid = (rhsBegin + rhsEnd) >> 1;
if (lhs[lhsMid] == rhs[rhsMid])
{
result = lhs[lhsMid];
break;
}
else if (lhs[lhsMid] < rhs[rhsMid])
{
lhsBegin = lhsMid;
rhsEnd = rhsMid;
} else
{
lhsEnd = lhsMid;
rhsBegin = rhsMid;
}
}
if (lhsBegin == lhsEnd && rhsBegin == rhsEnd)
result = min(lhs[lhsBegin], rhs[rhsBegin]);
else if (lhsBegin == lhsEnd - 1 && rhsBegin == rhsEnd - 1)
{
if (lhs[lhsBegin] < rhs[rhsBegin])
{
result = min(lhs[lhsEnd], rhs[rhsBegin]);
}
else
{
result = min(lhs[lhsBegin], rhs[rhsEnd]);
}
}
return result;
}
void main()
{
int lhs[] = {1, 2, 3, 4};
int rhs[] = {0, 2, 3, 4};
const int size = sizeof lhs / sizeof *lhs;
int result = findMidValue(lhs, rhs, size);
cout << "mid value = " << result << endl;
}
当两个数组长度不等时,这种情形比较复杂:
情形一:
当一个数组长度为1,另一个数组长度为奇数的情形:
例如A:1 B:2, 3, 4
这个时候的比较策略是,A的元素同B的中位数进行比较,若A的元素较小,则中位数一定是max(A[0], B[mid - 1]),若A的元素较大,则中位数一定是B[mid]
情形二:
例如A: 1 B:2, 3, 4, 5
这个时候的比较策略是,A的元素同B的中位数进行比较,若A的元素较小,则中位数一定是B[mid],若A的元素较大,则中位数一定是min(A[0], B[mid + 1])
下面引申一种情形:
当一个数组长度为2,另一个数组长度为奇数时:
例如A:1, 3 B:2, 4, 6
如果A[mid] < B[mid],那么A[mid]肯定不会是中位数,由于A只有两个元素,那么A[1]将会是中位数的候选对象,那么此情形退化为上面第一种情形
下面对一个例子进行分析:
数组A:1, 3, 5, 7, 9, 11
数组B:2, 4, 6, 8
第一轮:
数组A:1, 3, 5, 7, 9, 11
数组B:2,