【问题标题】:Finding the median of numbers in a LinkedList在 LinkedList 中查找数字的中位数
【发布时间】:2010-10-26 21:26:01
【问题描述】:

如何找到在 Java 中存储为 LinkedList 的数字列表的中位数?我不明白维基百科所指的选择算法。如果你能解释一下,加分。

【问题讨论】:

  • 可能您的第一步应该是将数据复制到数组/ArrayList 中。
  • 如果你不想找到中间值来干扰你的列表副本。但是,如果只是为了排序效率,Collections.sort() 无论如何都会在内部执行此操作。

标签: java linked-list median


【解决方案1】:

最好的算法是QuickSelect

阅读文章并尝试理解 QuickSort - 概念类似。

【讨论】:

  • 但是这个算法仍然是 linked 列表中最快的吗?似乎对于小 N,一种天真的方法可能会更好。
  • 会的。 QuickSelect 完全适用于链表(即使是纯函数式语言)!
【解决方案2】:

如果您想要一种快速编程的方式,请对列表进行排序并选择中间元素(或两个中间元素的平均值)。

更有效的选择算法本质上是尽量避免对列表中您实际上不需要排序的位进行排序,以找到给定 n 的第 n 个元素。 (JDK 目前不提供这种开箱即用的算法。)更新: 只是为了扩展我之前的帖子,更有效的方法示例包括:

  • 基于parallel sort 的选择,其初始阶段将数据放入多个“桶”中,然后对每个桶进行排序,但随后(在中位数的情况下)您实际上只对中间的“桶”进行排序,因为任何一方的桶中项目的精确顺序是无关紧要的
  • 基于分治排序算法(例如 Quicksort)进行选择,但同样,该算法实际上并不对超出所需范围的子列表进行排序。

【讨论】:

    【解决方案3】:

    中位数是排序列表中间的数字。 (对于条目数奇数的列表很容易,对于条目数为偶数的列表,它可以是两个“中间数字”之间的任意数字)

    所以对列表进行排序,找出中间的数字是多少。

    【讨论】:

    • 排序比选择中位数 (O(n)) 复杂得多 (O(nlogn))
    • 您提倡的 QuickSelect 会不会在 O(log n) 中运行?如果不是,你怎么说O(n)?
    • 其实他提倡的QuickSelect会在O(n)内运行。直观地说,它比 QuickSort 做的工作更少,因为在每一步它只继续查看数组的左半部分或右半部分。
    【解决方案4】:

    您基本上有两个主要选择:

    1. 简单快捷的方法 - 对O(nlogn) 中的列表进行排序。由于中位数被定义为一半的值大于它,一半的值小于它的值,因此只需取n/2th 值 - 这就是中位数。

    2. 如果这是一项对性能至关重要的任务,您可以应用各种选择算法,这些算法可以在好的情况下为您提供O(n)(但在最坏的情况下仍不能保证线性)。

    无论如何,请查看Selection Algorithms 上的维基百科条目,这应该可以让您对所有可用的方法有一个很好的总结。

    【讨论】:

      猜你喜欢
      • 2020-12-14
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      相关资源
      最近更新 更多