给定一个未排序的整数序列,它以流的形式流入您的程序。
整数太多,不适合记忆。
想象一下有一个功能:
int getNext() throws NoSuchElementException;
它返回流中的下一个整数。
编写一个函数来查找中位数。
解决O(n)中的问题。
有什么想法吗?
给出提示(使用堆数据结构..)
答案 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)复杂度中实现这一点。但在这种情况下,我仍然不明白使用堆。