在 O(logn) 中找到三个有序数组的中位数

Posted

技术标签:

【中文标题】在 O(logn) 中找到三个有序数组的中位数【英文标题】:Finding Median in Three Sorted Arrays in O(logn) 【发布时间】:2013-09-12 04:04:53 【问题描述】:

通过谷歌搜索几分钟,我知道了基本概念。

    让 A、B 和 C 成为包含 n 个元素的排序数组。 在每个数组中选取中值,并将它们命名为 medA、medB 和 medC。 不失一般性,假设 medA > medB > medC。 数组 A 中大于 medA 的元素不能成为三个数组的中位数。同样,数组 C 中小于 medC 的元素也不能,因此这些元素将被忽略。 递归地重复步骤 2-4。

我的问题是,基本情况是什么? 假设有很多基本情况,我手动测试了几个小时的算法,但我找不到正确的基本情况。 此外,三个数组的长度在每个递归步骤中都会变得不同。即使三个数组的长度不同,第4步是否有效?

【问题讨论】:

当三个数组的长度都小于一个常数时,你可以蛮力找到中位数。也有可能两个数组的长度为 1,但您不能忽略第三个数组中的元素。在这种情况下,您可以修改二分查找来找到中位数。 【参考方案1】:

该算法适用于两个大小相同但不是三个的排序数组。一次迭代后,您消除了 A 和 C 中的一半元素,但 B 保持不变,因此这些数组中的元素数量不再相同,该方法不再适用。对于不同大小的数组,如果使用相同的方法,则会从下半部和上半部移除不同数量的元素,因此剩余元素的中位数与原始数组的中位数不同。

话虽如此,您可以修改算法以在每次迭代中消除两端相同数量的元素,当一些数组非常小而一些数组非常大时,这可能是有效的。您也可以将其变成寻找第 k 个元素的问题,跟踪被丢弃的元素数量并在每次迭代时更改 k 的值。无论哪种方式,这都比两个数组的情况要复杂得多。

还有一篇关于一般案例的帖子:Median of 5 sorted arrays

【讨论】:

【参考方案2】:

我认为你可以使用选择算法,稍作修改以处理更多数组。

您正在寻找中位数,即 p=[n/2]th 元素。

选择最大数组的中位数,在其他两个数组中找到该值的分割点(二分查找,log(n))。现在您知道所选数字是第 k 个(k = 位置的总和)。

如果 k > p,则丢弃其上方 3 个数组中的元素,如果较小,则丢弃其下方(可以通过分别为每个数组维护上下索引来实现丢弃)。如果它更小,也更新 p = p - k。

重复直到 k=p。

糟糕,我认为这是 log(n)^2,让我考虑一下……

【讨论】:

以上是关于在 O(logn) 中找到三个有序数组的中位数的主要内容,如果未能解决你的问题,请参考以下文章

[二分查找] 两个等长有序数组的上中位数

在两个长度相等的排序数组中找到上中位数

递归打卡1在两个长度相等的排序数组中找到上中位数

Leet Code 4.寻找两个有序数组的中位数

循环有序数组的二分查找

有序数组寻找中位数以及寻找K大元素