在回复之前,请注意两个阵列的大小不同,请求的复杂度为O(min(log(n),log(m)),此问题从未在stackoverflow上询问过。
我一直在尝试修改O(log(n + m))解决方案,但不能,以下解决方案搜索第k个(合并数组的中位数)元素,但复杂性是log(n + M)。
为了在O(min(log(n),log(m)))中解决它,我们需要在每次递归调用时剪切第二个数组成员的k / 2。
更新的代码:
int select(int *a, int *b, int sa, int sb, int k) {
int ma = sa < k/2 ? sa - 1 : k/2 - 1;
int mb = k - ma - 2;
if (sa + sb < k)
return -1;
if (sa == 0)
return b[k - 1];
if (sb == 0)
return a[k - 1];
if (k == 1)
return a[0] < b[0] ? a[0] : b[0];
if (a[ma] == b[mb])
return a[ma];
if (a[ma] < b[mb])
return select(a + ma + 1, b, sa - ma - 1, mb + 1, k - ma - 1);
return select(a, b + mb + 1, ma + 1, sb - mb - 1, k - mb - 1);
}
/*
median:
uses select to find the median of the union of a and b (where a and b are sorted
positive integer arrays of sizes sa and sb respectively).
*/
int median(int *a, int *b, int sa, int sb) {
int m1, m2;
if ((sa + sb) % 2 == 1)
return select(a, b, sa, sb, (sa + sb)/2 + 1);
return select(a, b, sa, sb, (sa + sb)/2);
}
int main() {
int a[3] = {2, 4, 6};
int b[11] = {1, 3, 5, 7, 13, 17, 22, 23, 24, 25, 31};
printf("\n median is %d\n", median(a, b, 3, 11));
return 0;
}
我试图证明算法的时间复杂性和核心性没有运气。
答案 0 :(得分:0)
我们假设我们有两个数组A
和B
,大小分别为m
和n
,m <= n
。
然后我们有以下内容:
引理:A
和B
的中位数与A
和B'
的中位数相同,其中B'
是中间{{1} {}}或m
m + 1
元素,具体取决于B
和m
是否具有相同的奇偶校验。
现在,只能使用n
算法查找O(log(m + n))
和A
的中位数。
引理的证明:几乎是显而易见的......