我需要在不排序或复制数组的情况下找到数组的中位数。
该数组存储在cuda程序的共享内存中。将它复制到全局内存会降低程序的速度,并且共享内存中没有足够的空间来在那里制作额外的副本。
我可以使用两个'循环并迭代每个可能的值并计算小于它的值,但这将是O(n ^ 2)。不理想
现在有人使用O(n)或O(nlogn)算法来解决我的问题吗?
感谢。
答案 0 :(得分:3)
如果你的输入是绝对值小于C的整数,那么一个简单的O(n log C)算法只需要不变的额外内存:只需二进制搜索答案,即找到最小的数字x,这样x大于或等于阵列中的至少k个元素。它也可以通过并行前缀扫描轻松并行化来进行计数。
答案 1 :(得分:2)
你的时间,特别是内存限制使这个问题变得困难。但是,如果你能够使用近似中值,那就容易了。
假设元素 y 是ε近似中值,如果
m / 2 - εm<等级(y)< m / 2 +εm
然后您需要做的就是样本
t =7ε -2 日志(2δ -1 )
元素,并以任何你想要的方式找到它们的中位数。
请注意,您需要的样本数与数组的大小无关 - 它只是ε和δ的函数。< / p>