找到未排序的未排序数组的中位数

时间:2015-11-27 20:56:05

标签: arrays algorithm median

有没有办法找到未排序数组的中位数: 1-没有排序。 2-不使用选择算法,也不使用中位数的中位数

我发现了许多类似于我的其他问题。但解决方案,其中大部分,如果不是全部,讨论了SelectProblem和MedianOfMedians

3 个答案:

答案 0 :(得分:13)

你可以在没有排序的情况下找到数组的中位数。有效的做法并不容易。

例如,您可以迭代数组的元素;对于每个元素,计算小于等于它的元素数,直到找到具有正确计数的值。这将是O(n 2 )时间,但只有O(1)空间。

或者你可以使用一个最小堆,其大小只是数组大小的一半。 (也就是说,如果数组具有std2k元素,则堆应该具有2k+1个元素。)使用标准堆构建算法使用第一个数组元素构建堆(这是O(N))。然后,对于每个剩余的元素k+1,如果x大于堆的最小值,则将min元素替换为x并执行SiftUp操作(即O(log) N))。最后,中值是堆的最小元素(如果原始数组的大小是奇数)或者是堆中两个最小元素的平均值。因此,如果不能重新排列数组元素,那么总共有O(n log n)时间和O(n)空间。 (如果您可以重新排列数组元素,则可以就地执行此操作。)

答案 1 :(得分:4)

有一种随机算法能够在O(n)步骤(平均情况场景)中完成此任务,但它确实涉及对数组的某些子集进行排序。并且,由于其随机性,不能保证它实际上会完成(尽管这种不幸的事件应该以消失的概率发生)。

我将在这里留下主要想法。有关此算法工作原理的更详细说明和证据,请查看here

A成为您的数组并让n=|A|。让我们假设A的所有元素都是不同的。算法如下:

  1. t = n^(3/4)随机选择A个元素。
  2. T成为所选元素的“集合”。排序T
  3. 设置pl = T[t/2-sqrt(n)]pr = T[t/2+sqrt(n)]
  4. 遍历A的元素并确定有多少元素小于pl(由l表示)以及多少元素大于pr(由{表示} {1}})。如果是rl > n/2,请返回第1步。
  5. r > n/2成为MA之间pl中的元素集。 pr可以在步骤4中确定,以防万一我们到达第5步。如果M的大小不超过M,请排序4t。否则,请返回步骤1.
  6. 返回M作为中位元素。
  7. 算法背后的主要思想是获得包含中间元素的两个元素(m = M[n/2-l]pl)(即pr< pl< {{ 1}})这两个在数组的有序版本中彼此非常接近(并且在没有实际排序数组的情况下这样做)。很有可能,所有六个步骤只需要执行一次(即,您将获得mpr来自第一个并且仅通过步骤1-5的这些“好”属性,所以不要去回到步骤1)。一旦找到两个这样的元素,您可以简单地对它们之间的元素进行排序,并找到pl的中间元素。

    第2步和第5步确实涉及一些排序(这可能违背了你神秘建立的“规则”:p)。如果在表上对子数组进行排序,则应使用一些排序方法在pr步骤中执行此操作,其中A是要排序的数组的大小。由于O(slogs)s明显小于T,因此排序步骤采用“少于”M步骤。如果它也违反了对子数组进行排序的规则,那么考虑到在这两种情况下都不需要排序。您只需要找到一种方法来确定AO(n)pl,这只是另一个选择问题(具有相应的索引)。排序prm确实可以实现此目的,您可以使用任何其他选择方法(可能是之前建议的rici)。

答案 2 :(得分:0)

http://www.aip.de/groups/soe/local/numres/bookfpdf/f8-5.pdf描述了非破坏性的常规selip()。它通过数据进行多次传递,在每个阶段随机选择当前值范围内的项目,然后计算项目数量以建立随机选择的等级。