如何找到两个排序数组之间的中位数?

时间:2018-01-22 16:37:20

标签: python arrays algorithm

我正在研究竞争性编程问题,我们试图找到两个排序数组的中位数。最佳算法是执行二进制搜索并识别两个数组之间的分裂点ij

我自己无法获得解决方案。我不明白最初的逻辑。到目前为止,我将按照我对这个问题的看法。

中位数的概念是将给定数组分成两组。合并两个给定的数组后,请考虑假设的left数组和假设的right数组。这两个数组的长度都相同。

我们知道给出这两个假设数组的中位数是[max(left) + min(right)]/2。到目前为止这是有道理的。但是这里的问题现在知道如何构造leftright数组。

我们可以选择ArrayA上的分割点iArrayB上的分割点j。请注意len(ArrayB[:j] + ArrayB[:i]) == len(ArrayB[j:] +ArrayB[i:])

现在我们只需要找到切割点。我们可以尝试所有分裂点ij,使它们满足中值条件。然而,这可能是O(m*n) where M is size of ArrayB and where N is size of ArrayA

我不确定如何使用我的思路来获得二元搜索解决方案的位置。如果有人能给我指点 - 那就太棒了。

1 个答案:

答案 0 :(得分:2)

这是我设法提出的方法。

首先,我们知道结果数组将包含 N + M 元素,这意味着左侧部分将包含(N + M)/ 2 元素,并且右边的部分也包含(N + M)/ 2 元素。我们将结果数组表示为 Ans ,并将其中一个部分的大小表示为 PartSize

对阵列 A 执行二进制搜索操作。这种二分搜索的范围是[ 0 N ]。此二进制搜索操作将帮助您确定阵列 A 中的元素数量,这些元素将构成生成数组的部分。

现在,假设我们正在测试值 i 。如果 i 数组 A 中的元素应该包含在结果数组的左侧部分中,则表示 j = PartSize - i 元素必须包含在第一部分的 B 数组中。我们有以下可能性:

  • j> M 这是一个无效的状态。在这种情况下,这意味着我们仍然需要从数组 A 中选择更多元素,因此我们的新二进制搜索范围变为[ i + 1 N ]

  • j< = M & A [i + 1]< B [j] 这是一个棘手的案例。想一想。如果数组 A 中的下一个元素小于数组 B 中的元素 j ,则表示元素 A [i + 1 ] 应该在左侧而不是元素 B [j] 。在这种情况下,我们的新二进制搜索范围变为[ i + 1 N ]。

  • j< = M & A [i]> B [j + 1] 这与前一案例很接近。如果数组 B 中的下一个元素小于数组 A 中的元素 i ,则表示元素 B [j + 1] ] 应该在左侧而不是元素 A [i] 。在这种情况下,我们的新二进制搜索范围变为[ 0 i-1 ]。

  • j< = M & A [i + 1]> = B [j] & A [i]< = B [j + 1] 这是最佳情况,您终于找到了答案。

二进制搜索操作完成后,您设法计算 i j ,您现在可以轻松找到中位数的值。你需要在这里处理一些案例,具体取决于 N + M 是奇数还是偶数。

希望它有所帮助!