有效的分组,排序和返回前N个结果的方法

时间:2016-07-06 08:42:27

标签: algorithm sorting grouping average

我有一个流(或长元素列表,可能是数千或数百万),我必须返回前N组(在我的情况下为24),按组的平均值排序。所以项目的形式如下:

{groupId: 1, value: 10}, {groupId: 2, value: 4}, {groupId: 1: value: 2}

和表单组:

{groupId: 1, average: 6}, {groupId: 2: average}

显然,天真的解决方案是按平均值对组进行迭代,分组和排序,并返回前24个组。对于可以处理数百万件物品的高性能解决方案有什么想法吗?

2 个答案:

答案 0 :(得分:1)

为每个组保留两个值 - 该组和计数器的值的总和。最后用计数器除以得到该组的平均值。

您无法保留有限数量的群组的信息,因为任何群组可能会在某个时刻成为领导者。

答案 1 :(得分:1)

您无法逃避遍历整个列表以获取给定组的每个成员。一旦您的每个组都有其均值,您可以执行以下操作:

  1. N 第一组带入矢量/数组。
  2. 从该数组中创建一个堆,使得堆的顶部是具有最大平均值的组。
  3. 对于每个剩余的组,将其与堆顶部进行比较:
    • 如果当前组大于堆顶部,则丢弃它
    • 如果它更小,则弹出堆顶部并插入当前组
  4. 最后,您在堆中拥有所有 N 个第一组。您可以通过应用堆排序的最后一步并反转您获得的容器(因为堆是最大堆)来按顺序获取它们。

    总体复杂性:(其中 K 是上面定义的群组总数和 N

      

    O(N +(KN).ln(N)+ N.ln(N) = O(N + K.ln(N))

    • 术语 N 来自第一个 N 组并制作初始最大堆。
    • 术语(KN).ln(N)来自(删除顶部/插入当前组)操作对(最多 K - N
    • 最后一个术语( N.ln(N))用于排序最终堆。