我知道可以计算O(n)中数字列表的平均值。但中位数呢?是否有比排序(O(n log n))和查找中间元素更好的算法(如果列表中的偶数项,则是两个中间元素的平均值)?
答案 0 :(得分:16)
答案 1 :(得分:13)
您所谈论的是selection algorithm,其中k = n/2
。有一种基于quicksort中使用的相同分区函数的方法。毫不奇怪,它被称为quickselect。虽然它可以像quicksort一样具有O(n 2 )最坏情况,但可以使用proper pivot selection将其降低到线性时间。
答案 2 :(得分:6)
部分无关紧要,但是:快速提示如何在网上快速找到常见基本问题的答案。
高效计算样本中位数
即使排序n个项目一般采用O(n log n)操作,通过使用“分而治之”算法,n个项目的中位数只能用O(n)运算来计算(事实上,你总是可以使用此方法查找值列表的第k个元素;这称为selection problem)。
...有最坏情况的线性时间选择算法。 ...
答案 3 :(得分:4)
如果数字是离散的(例如整数)并且存在可管理数量的不同值,则可以使用“桶排序”(O(N)),然后迭代桶以确定哪个桶保持中位数。完整的计算时间为O(N),空间为O(B)。
答案 4 :(得分:2)
只是为了好玩(谁知道,它可能更快)还有另一个随机中位数算法,在Mitzenmacher和Upfall的书中进行了技术解释。基本上,你选择一个多项式较小的列表子集,并(用一些花哨的书籍)使它可能包含真实的中位数,然后用它来找到真正的中位数。这本书是在谷歌书籍上,这是一个link。注意:我能够阅读algorthm的页面,因此假设Google图书向所有人显示相同的页面,您也可以阅读它们。
这是一个随机算法s.t.如果它找到了答案,则100%肯定它是正确的答案(这称为拉斯维加斯风格)。随机性来自运行时间 - 偶尔(概率为1 /(sqrt(n)),我认为)它找不到中位数,并且必须重新运行。
渐近地,当你考虑失败的机会时,它是完全线性的 - 也就是说,它是一个小于线性的,当你考虑到你可能需要的次数时重新运行它,它变成线性的。
注意:我不是说这更好或更糟 - 我当然没有在这些算法之间进行真实的运行时比较!我只是提出了一个具有线性运行时的附加算法,但工作方式却截然不同。
答案 5 :(得分:1)
此链接最近在计算中位数时出现:http://matpalm.com/median/question.html。
总的来说,我认为你不能超过O(n log n)时间,但我没有任何证据:)。无论您将多少并行,将结果聚合为单个值至少需要log n级执行。
答案 6 :(得分:1)
尝试随机算法,采样大小(例如2000)独立于数据大小n,仍然能够获得足够高(99%)的准确度。如果您需要更高的精度,只需增加采样大小。使用Chernoff边界可以证明某个采样大小下的概率。我已经编写了一些JavaScript代码来实现该算法,随时可以使用它。 http://www.sfu.ca/~wpa10