在O(min(log(n),log(m))复杂度中找出两个不同大小的排序数组的中位数

时间:2016-05-06 20:13:15

标签: c++ arrays algorithm median sorted

在回复之前,请注意两个阵列的大小不同,请求的复杂度为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;
} 

我试图证明算法的时间复杂性和核心性没有运气。

1 个答案:

答案 0 :(得分:0)

我们假设我们有两个数组AB,大小分别为mnm <= n

然后我们有以下内容:

引理:AB的中位数与AB'的中位数相同,其中B'是中间{{1} {}}或m m + 1元素,具体取决于Bm是否具有相同的奇偶校验。

现在,只能使用n算法查找O(log(m + n))A的中位数。

引理的证明:几乎是显而易见的......