从整数流中找出中位数

时间:2010-08-09 14:19:08

标签: algorithm

给定一个未排序的整数序列,它以流的形式流入您的程序。

整数太多,不适合记忆。

想象一下有一个功能:

int getNext() throws NoSuchElementException;

它返回流中的下一个整数。

编写一个函数来查找中位数。

解决O(n)中的问题。

有什么想法吗?

给出提示(使用堆数据结构..)

4 个答案:

答案 0 :(得分:9)

你必须保持两个堆一个最大堆(包含迄今为止看到的最小N / 2个元素)和一个最小堆(包含最大的N / 2个元素)。如果N是奇数,则将额外元素存放在一边。

无论何时调用函数getNext(),

如果N变为奇数,则将新元素保存为额外元素。如有必要,将该元素与min-heap或max-heap中的元素交换以满足以下条件

max(max-heap)< = extra element< = min(min-heap)。

如果N变为偶数,则执行与上面相同的操作以获得第二个额外元素。然后,将较小的一个添加到max-heap,将较大的一个添加到min-heap。 插入应为O(log N)

获得中位数:O(1)
如果N是奇数,则中位数是额外元素 如果N是偶数,则中位数是2个堆的顶部之间的平均值

答案 1 :(得分:2)

paper。它(可能)需要不止一次通过。这个想法是,在每次传递中,计算上限和下限,使得中位数位于它们之间。

这里的基本结果是 N =数据大小, P =通过次数

定理2) P -pass算法选择 K th 最高的 N 元素需要 最多储存 O(N 1 / P (log N)(2- 2 < / SUP> / <子> P

此外,对于非常少量的存储 S ,即 2 <= S <= O((log N) 2 )< / em>,有一类使用的选择算法 最多 O((log N) 3 / S 通过。

阅读论文。我不确定堆与它有什么关系

答案 2 :(得分:0)

假设维持中位数的窗口是K. 构造K编号的二叉搜索树。好); 按顺序遍历并找到第(K / 2)个元素.O(K / 2);

总时间为O(K)。

答案 3 :(得分:0)

使用选择算法,我们可以在O(n)复杂度中实现这一点。但在这种情况下,我仍然不明白使用堆。