很多机器,每台机器上都有很一部分数据,如何输出分布在所有机器上的所有数据的median
转化一下,
There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
有两个数组,如何求两个数组的中间值?
找到一篇文章,慢慢读之:
http://www.leetcode.com/2011/03/median-of-two-sorted-arrays.html
另:自己想了一个方法 (passed testing)
使用辅助数组k1, k2来记录对应的原数组的当前位置的值,在整个m+n数组中排序后的index值
指定两个指针p1, p2,分别指定到两个数组上,开始遍历
然后比较 p1[midx] and p2[nidx]的值
1. ==, 则p1, p2同时向后移动,并且填充辅助数组k1, k2
2. >=, 则p2移动, p1不移动,同时把当前的总index值记录到辅助数组k2中
3. <=, 则p1移动, p2不移动,同时把当前的总index值记录到辅助数组k1中
如果有超出部分,单独循环剩下的部分(如p2)
然后再扫描k1, k2,只要其值 == index/2,则对应的a[midx]或b[nidx]即为最后需要查找的中间值
典型的空间换时间,该方法最大的不足,就是空间占用太多。O(m+n),当然,时间也是O(m+n)
不过,相对来说,算法简单易懂,代码书写容易,也算是优点吧。
View Code
// Get Median of Two Sorted Arrays
int GetMedianOf2Arrays(int a[], int m, int b[], int n)
{
assert(NULL != a && NULL != b && m <= n);
int *p1 = a;
int *p2 = b;
int index =0;
int midx = 0, nidx = 0;
int *k1 = new int[m];
int *k2 = new int[n];
// 使用辅助数组k1, k2来记录对应的原数组的当前位置的值,在整个m+n数组中排序后的index值
// 指定两个指针p1, p2,分别指定到两个数组上,开始遍历
// 然后比较 p1[midx] and p2[nidx]的值
// 1. ==, 则p1, p2同时向后移动,并且填充辅助数组k1, k2
// 2. >=, 则p2移动, p1不移动,同时把当前的总index值记录到辅助数组k2中
// 3. <=, 则p1移动, p2不移动,同时把当前的总index值记录到辅助数组k1中
// 如果有超出部分,单独循环剩下的部分(如p2)
// 然后再扫描k1, k2,只要其值 == index/2,则对应的a[midx]或b[nidx]即为最后需要查找的中间值
while (midx < m && nidx < n) // 只要有一个数组跑完,则停止循环
{
if (a[midx] == b[nidx]) // 如果当前的a和b值相等
{
k1[midx] = index;
k2[nidx] = index;
++midx;
++nidx;
++index;
}
else if (a[midx] < b[nidx])
{
k1[midx] = index;
++midx;
++index;
}
else
{
k2[nidx] = index;
++nidx;
++index;
}
}
while (nidx < n)
{
k2[nidx] = index;
++nidx;
++index;
}
// 上一步中, index 已经++,所以这里直接index/2
int retIdx = index/2;
int value = 0;
bool found = false;
for (int i = 0; i < m; ++i)
{
if (k1[i] > retIdx)
break;
if (k1[i] == retIdx)
{
found = true;
value = a[i];
break;
}
}
if (!found)
for (int i = 0; i < n; ++i)
{
if (k2[i] > retIdx)
break;
if (k2[i] == retIdx)
{
value = b[i];
break;
}
}
delete[] k1;
delete[] k2;
return value;
}