【问题标题】:How to find the kth smallest element of a list without sorting the list?如何在不排序列表的情况下找到列表的第 k 个最小元素?
【发布时间】:2015-10-07 21:18:18
【问题描述】:

我需要在不排序或复制数组的情况下找到数组的中位数。

数组存储在 cuda 程序的共享内存中。将其复制到全局内存会减慢程序速度,并且共享内存中没有足够的空间来复制它。

我可以使用两个“for”循环并遍历每个可能的值并计算有多少值小于它,但这将是 O(n^2)。不理想

现在有人知道解决我的问题的 O(n) 或 O(nlogn) 算法吗?

谢谢。

【问题讨论】:

  • 可能是QuickSelect?
  • @higuaro 我不确定如何在不对数组进行排序的情况下实现 QuickSelect。也许我错了。
  • @user403348255 这个问题实际上并没有解决无法对数组进行排序的问题。
  • @Gottfried QuickSelect 不一定会对您的数组进行排序,它只会在搜索期间围绕所选枢轴重新排序数据。该算法不需要排序数组作为输入

标签: arrays algorithm cuda


【解决方案1】:

如果您的输入是绝对值小于 C 的整数,则有一个简单的 O(n log C) 算法,只需要恒定的额外内存:只需对答案进行二进制搜索,即找到最小的数 x 使得 x 更大大于或等于数组中的至少 k 个元素。它也很容易通过并行前缀扫描进行并行化以进行计数。

【讨论】:

  • 我很难理解你的意思。你在说什么“简单”算法?你是如何对未排序的列表进行二分搜索的?如果列表已排序,那么当我可以 get 第 k 个元素时,为什么我需要对第 K 个元素进行二进制搜索?
【解决方案2】:

您的时间,尤其是内存限制使这个问题变得困难。但是,如果您能够使用近似中位数,这将变得很容易。

假设元素y是一个ε近似中位数如果

m/2 - ε m

那么你需要做的就是样品

t = 7ε−2 对数(2δ -1 )

元素,并以任何你想要的方式找到它们的中值。


请注意,您需要的样本数量与数组的大小无关 - 它只是 εδ 的函数。

【讨论】:

    猜你喜欢
    • 2019-08-20
    • 1970-01-01
    • 2011-06-28
    • 2012-10-22
    • 2014-11-27
    • 2021-11-01
    • 1970-01-01
    • 2017-03-04
    相关资源
    最近更新 更多