查找范围内元素数量的最快方法

Posted

技术标签:

【中文标题】查找范围内元素数量的最快方法【英文标题】:Fastest way to find number of elements in a range 【发布时间】:2015-05-01 04:47:12 【问题描述】:

给定一个带有n elements的数组,如何在O(log n)better的给定范围index i to index j中找到greaterequal到给定value (x)的元素数量? /p>

我的实现是这样的,但它是O(n)

for(a=i;a<=j;a++)
    if(p[a]>=x) // p[] is array containing n elements
    count++;

【问题讨论】:

如果你对数组进行排序,你也许可以使用二分搜索。根据定义,可以添加排序数组中大于第一个匹配项的每个值,而无需额外处理。 @timrau 它没有被订购 @ElliottFrisch 但是如果我对数组进行排序,索引 i,j 之间的元素会有所不同, 可以先对数组进行预处理吗? @ProgrammerPerson 给了我一个数组,接下来给定了一些查询 (i,j,x) ,我需要在 (i,j) 范围内找到大于或等于 x 的元素数每个查询 【参考方案1】:

如果允许您对数组进行预处理,那么使用O(n log n) 预处理时间,我们可以在O(log n) 时间回答任何[i,j] 查询。

两个想法:

1) 请注意,能够回答[0,i][0,j] 查询就足够了。

2) 使用持久*平衡顺序统计二叉树,它维护 n 个版本的树,版本 i 由版本 i-1 通过添加 a[i] 形成。要回答 query([0,i], x),您可以查询版本 i 树中的元素数量 &gt; x(基本上是排名信息)。订单统计树可让您做到这一点。

*:持久化数据结构是一种优雅的函数式编程概念,用于不可变数据结构,并且具有高效的构造算法。

【讨论】:

只有在有大量查询 (x >> log(n)) 时才值得这样做,否则预先排序会比只检查 i 和 @ 之间的所有内容产生更糟糕的时间987654329@. @Raniz:是的,这是真的。不过,x &gt; log(n) 并不是很大。例如,对于 x = 100 万,我们正在讨论超过 20 个查询。 我需要将(i,j) of p[] 范围内的元素与x 和p[] 包含n 元素进行比较,并且这个(i,j,x) 集合对于同一个数组p[] 被多次给出/跨度> @polasairam:我想你说的是观察 1)?我建议您考虑一下...(或者您的评论是针对 Raniz 的?在这种情况下,我建议您使用 @ 功能...) @polasairam:是 O(nlog n + K log n),其中 K 是查询数。【参考方案2】:

如果数组已排序,您可以通过二分搜索找到小于 X 的第一个值,大于 X 的元素数是该元素之后的项目数。那将是 O(log(n))。

如果数组未排序,则无法在小于 O(n) 的时间内完成,因为您必须检查每个元素以检查它是否大于或等于 X。

【讨论】:

【参考方案3】:

在 O(log N) 中不可能,因为您必须检查所有元素,因此需要 O(N) 方法。

标准算法基于快速排序的分区,有时称为快速选择

这个想法是您不对数组进行排序,而只是对包含 x 的部分进行分区,并在 x 是您的枢轴元素时停止。该过程完成后,您将拥有 x 右侧的所有元素 x 和更大的元素。这与查找第 k 个最大元素时的过程相同。

在How to find the kth largest element in an unsorted array of length n in O(n)? 上了解一个非常相似的问题。

索引 i 到 j 的要求并不是给问题带来任何复杂性的限制。

【讨论】:

先生,x 可能包含也可能不包含在 array p[] 中,【参考方案4】:

鉴于您的要求是数据未预先排序并且在查询之间不断变化,O(n) 是您希望达到的最佳复杂度,因为无法计算大于或等于 some 的元素数量值而不看所有这些。

如果您考虑一下,这相当简单:如果您事先不知道它是如何表示/排序的,那么您就无法避免检查范围内的每个元素以进行任何类型的搜索。

您可以构建一个平衡的二叉树,甚至可以即时进行基数排序,但您只是将其他地方的开销推向相同的线性或更糟的线性 O(NLogN) 复杂度,因为此类算法再次让您检查每个元素在范围内首先对其进行排序。

所以这里的 O(N) 实际上没有任何问题。这是理想的情况,您正在考虑改变外部涉及的数据的整体性质以允许提前对其进行有效排序或进行微优化(例如:并行处理具有多个线程的子范围,前提是它们'足够厚实)来调整它。

在您的情况下,您的要求似乎很严格,因此后者似乎是借助分析器的最佳选择。

【讨论】:

以上是关于查找范围内元素数量的最快方法的主要内容,如果未能解决你的问题,请参考以下文章

获得范围内频率平均值的最快方法[关闭]

如何查找 iBeacon 范围内的设备数量?

Python - 在给定的大数范围内找到所有完美正方形的最快方法

C ++:在范围内获取整数的最快方法

查找一维数组的不同元素数量的最快和最有效的方法

检查范围内容差是不是相等的最快方法?