C++程序 在数据流中查找第k大元素
给定一个无限的整数流,查找任何时刻的第k大元素。
例子:
输入:
stream[] = {10, 20, 11, 70, 50, 40, 100, 5, …}
k = 3
输出: {_, _, 10, 11, 20, 40, 50, 50, …}
允许的额外空间为O(k)。
一个 简单的解决方案 是保持大小为k的数组。想法是让数组排序,以便可以在O(1)时间内找到第k大的元素(如果数组按增量顺序排序,我们只需返回数组的第一个元素)。
如何处理流的新元素?
对于流中的每个新元素,请检查新元素是否小于当前的第k大元素。如果是,则忽略它。否则,从数组中删除最小元素并以排序顺序插入新元素。处理新元素的时间复杂度为O(k)。
一个 更好的解决方案 是使用大小为k的自平衡二叉搜索树。可以在O(Logk)时间内找到第k大的元素。
如何处理流的新元素?
对于流中的每个新元素,请检查新元素是否小于当前的第k大元素。如果是,则忽略它。否则,从树中删除最小元素并插入新元素。处理新元素的时间复杂度为O(Logk)。
一个 高效的解决方案 是使用大小为k的小根堆来存储流的k个最大元素。第k大的元素始终位于根处,并且可以在O(1)时间内找到它。
如何处理流的新元素?
将新元素与堆的根进行比较。如果新元素较小,则忽略它。否则,将根替换为新元素并对修改后的堆的根进行堆化调用。找到第k大的元素的时间复杂度为O(Logk)。
输出:
时间复杂度: O(N * log K)
使用优先队列实现:
输出
时间复杂度: O(N * log K)
辅助空间: O(K)