【问题标题】:Is it possible to calculate median of a list of numbers better than O(n log n)?是否可以比 O(n log n) 更好地计算数字列表的中位数?
【发布时间】:2026-02-04 14:40:01
【问题描述】:

我知道可以计算 O(n) 中数字列表的平均值。但是中位数呢?有没有比排序 (O(n log n)) 和查找中间元素(或者如果列表中的项目数为偶数,则为两个中间元素的平均值)更好的算法?

【问题讨论】:

    标签: algorithm language-agnostic math


    【解决方案1】:

    【讨论】:

    • 该链接谈论的是“中位数的中位数”,或者换句话说,是“真实”中位数的近似值。我不确定这是 OP 要求的。
    • 使用确定性选择,您可以获得真正的中位数。见这里:en.wikipedia.org/wiki/Selection_algorithm
    • @Chris Jester-Young:它确实谈到了“中位数的中位数”,但只是作为算法中的一个中间值——而不是结果!该算法确实在 O(N)、最坏情况、时间中找到中位数(不是中位数的中位数)。
    • +1。但请注意,它需要 24n 次比较,这意味着它可能比平均 1.5n 次比较的随机方法慢得多。 (从链接页面的最后两段获取或推断的数字。)
    • 链接已失效。
    【解决方案2】:

    您所说的是selection algorithm,其中k = n/2。有一种基于快速排序中使用的相同分区函数的方法。毫不奇怪,它被称为quickselect。虽然它可以像快速排序一样有 O(n2) 最坏情况,但可以使用 proper pivot selection 将其降低到线性时间。

    【讨论】:

      【解决方案3】:

      部分无关,但是:关于如何在网络上快速找到此类常见基本问题的答案的快速提示。

      样本中位数的高效计算

      尽管对 n 项进行排序通常需要 O(n log n) 次操作,但通过使用“分而治之”算法,只需 O(n) 次操作即可计算 n 项的中位数(事实上,您总是可以使用此方法查找值列表的第 k 个元素;这称为 selection problem)。

      • 按照算法描述的选择问题的链接。阅读简介:

      ... 有最坏情况的线性时间选择算法。 ...

      【讨论】:

        【解决方案4】:

        如果数字是离散的(例如整数)并且存在可管理数量的不同值,则可以使用 O(N) 的“桶排序”,然后遍历桶以找出哪个桶拥有中位数.完整的计算时间为 O(N),空间为 O(B)。

        【讨论】:

          【解决方案5】:

          只是为了好玩(谁知道,它可能更快)还有另一种随机中值算法,在 Mitzenmacher 和 Upfall 的书中进行了技术解释。基本上,您选择列表的多项式较小的子集,并且(使用一些精美的书本)使其可能包含真正的中位数,然后使用它来找到真正的中位数。这本书在谷歌图书上,这里是link。注意:我能够阅读算法的页面,因此假设 google 图书向所有人显示相同的页面,您也可以阅读它们。

          这是一个随机算法 s.t.如果它找到答案,则 100% 确定它是正确答案(这被称为拉斯维加斯风格)。随机性来自运行时 --- 偶尔(我认为概率为 1/(sqrt(n)))它无法找到中位数,必须重新运行。

          渐近地,当你考虑到失败的机会时,它完全是线性的——也就是说,它比线性少一点,正是这样,当你考虑到你可能需要的次数时重新运行它,它变成线性的。

          注意:我并不是说这是更好或更坏 --- 我当然没有对这些算法进行真实的运行时比较!我只是提出了一个额外的算法,它具有线性运行时间,但工作方式明显不同。

          【讨论】:

            【解决方案6】:

            最近在计算中位数时弹出此链接:http://matpalm.com/median/question.html

            一般来说,我认为你不能超过 O(n log n) 时间,但我没有任何证据证明:)。不管你让它并行多少,将结果聚合成一个值至少需要 log n 级的执行。

            【讨论】:

            • 我将您的答案从“O(log n)”更改为“O(n log n)”,我认为,考虑到问题和您的其他答案,这就是您正在寻找的.
            【解决方案7】:

            尝试随机算法,采样大小(例如2000)与数据大小n无关,仍然能够获得足够高(99%)的准确度。如果您需要更高的精度,只需增加采样大小即可。使用 Chernoff 界可以证明一定抽样规模下的概率。我已经编写了一些 JavaScript 代码来实现该算法,请随意使用。 http://www.sfu.ca/~wpa10

            【讨论】: