从运行流中无限多个元素的数组返回最大k个元素的最优算法

时间:2015-06-18 12:00:56

标签: arrays algorithm data-structures stream

我有一个正在运行的整数流,如何在任何时间点从该流中获取最大的k个元素。

2 个答案:

答案 0 :(得分:15)

最简单的解决方案是填充min-heap大小k

首先,使用第一个k元素填充堆。

接下来,对于流中的每个元素 - 检查它是否大于堆的头部,如果是 - 弹出当前头部,然后插入新元素。

在流中的任何时刻 - 堆都包含最大的k元素。

此算法为O(nlogk),其中n是到目前为止在流中遇到的元素数。

另一种解决方案,在某些情况下,在渐近复杂性方面稍微复杂但理论上更好,是保留2k元素的数组。

首先,加载前2k个元素。
运行Selection Algorithm,找出最高k。放弃其余部分,此时数组中只剩下k个元素。
现在,再次使用下一个k元素填充数组,然后重复。

在每个点上,数组包含k个最大元素,最多k个元素不是最大的元素。您可以为此阵列上的每个查询运行选择算法。

运行时分析:

维护阵列:每个选择算法都是O(2k) = O(k)。每k个元素执行一次,n/k次,如果n表示到目前为止看到的元素数量,则为O(n/k * 2k) = O(n)

此外,每个查询都是O(k),如果查询的数量为Q,则会为我们提供O(n + Q*k)运行时。

为了提高效率,我们需要Q*k < nlogk

Q*k < nlogk
Q < n/k * logk

因此,如果如上所述限制查询的数量,则此解决方案在渐近复杂度方面可能更有效。

在实践中,获得top k通常是通过使用min-heap解决方案来完成的,至少在我看到它需要的时候。

答案 1 :(得分:0)

def gse(y_true, y_pred):
    # some tensor operation on y_pred and y_true
    return K.mean(K.square(y_pred - y_true), axis=-1)

nsmallest或nlargest方法采用参数k和要在其中找到最小/最大元素的数组