Java 从N列表中查找K最大值

Java 从N列表中查找K最大值,java,Java,我有要求- 1.在列表/数组中有随机值,我需要找到3个最大值。 2.我有一个值池,每次更新该池可能是在每5秒,现在每次更新后,我需要从列表池中找到3个最大值 我曾三次想到使用Math.max,但我认为这并不合适 一个非常优化的方法。 >任何排序机制都不会很昂贵,因为我只关心top 3个最大值,为什么要对所有这些进行排序 请建议用JAVA实现此功能的最佳方法 对列表进行排序,获得3个最大值。如果您不想增加排序的开销,请迭代并维护n个最大值 维护池是一个已排序的集合 更新:仅供参考,Guava有一个

我有要求- 1.在列表/数组中有随机值,我需要找到3个最大值。 2.我有一个值池,每次更新该池可能是在每5秒,现在每次更新后,我需要从列表池中找到3个最大值

我曾三次想到使用Math.max,但我认为这并不合适 一个非常优化的方法。 >任何排序机制都不会很昂贵,因为我只关心top 3个最大值,为什么要对所有这些进行排序

请建议用JAVA实现此功能的最佳方法

  • 对列表进行排序,获得3个最大值。如果您不想增加排序的开销,请迭代并维护n个最大值
  • 维护池是一个已排序的集合
  • 更新:仅供参考,Guava有一个带有
    greatestOf
    方法的排序类,用于获取集合中的n max元素。您可能需要检查实现


    遍历列表一次,保留迄今为止看到的三个最大元素的有序数组。每当你看到一个新元素时,这是很容易更新的,它会立即给你你想要的答案。

    a应该是你在这种情况下需要的数据结构

    首先,明智的做法是不要再说“我认为这不是一种非常优化的方法。”除非你在代码中安装了探查器,否则你不会知道代码的哪一部分正在减慢速度

    其次,最简单的方法是使用
    Collections.sort()
    ,然后选择最后三个元素,这是您正在尝试做的事情——如果有人以后试图查看您的代码,他们会非常清楚的。然后,任何看到代码的人都会知道,“哦,这段代码包含了三个最大的元素。”清晰的代码有着巨大的价值,它可能会超过您可能进行的任何优化。它还可以防止您编写错误,例如,当有人将相同的数字放入列表两次时,会给出一个自然的含义,或者当列表中只有两个元素时,会给出一条有用的错误消息


    第三,如果你得到的数据太大以至于O(n log n)操作太慢,你应该重写首先保存数据的数据结构--
    java.util.NavigableSet
    例如提供了一个
    .degendingIterator()
    方法,你可以探测它的前三个元素,这将是最大的三个数字。如果您真的愿意,可以使用堆数据结构,您可以通过类似于一次比较的方式提取前3个元素,代价是添加一个O(logn)过程。

    如果列表过长,然后,或者有没有其他方法可以更新排序问题scenario@bunta使用双链接列表或只使用反向排序,前3个是从尾部开始的前3个或最后3个。您可以在O(n)而不是O(n log n)中执行此操作。对于项目1,如果您刚刚得到一个列表,您可以简单地迭代该列表并保持三个最大值。这将比实际排序更有效。您还可以迭代列表,将所有元素放置在一个已排序的集合(如树)中,然后获得3个最大值。这比仅迭代并获得3个最大值的效率稍低。更新时,值是被替换和删除的,还是仅被添加的?您必须理解“昂贵”是一个相对术语。作为一名程序员,你总是在权衡各种成本。排序的代价是O(n logn)。这意味着,即使对于非常大的集合,排序列表的成本增长也不会比简单地遍历列表快多少。一些快速测试显示,我能在笔记本电脑上制作的最大阵列大小约为2^27,我能在5秒内用
    阵列进行排序的最大阵列。排序(int[]nums)
    为2^24(1670万个条目)。如果你要从少于一百万人的名单中选出前三名,只需对其进行排序。从问题的措辞来看,他似乎不知道添加了什么或添加了多少。遗漏了一个动词,编辑了。无论如何,这是更好的,因为它的O(n)和简单,任何时候改变列表只是重新遍历。