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

Java 查找范围内元素数量的最快方法,java,c++,algorithm,Java,C++,Algorithm,给定一个包含n个元素的数组,如何在O(logn)中的索引i到索引j或复杂度更好的范围内找到大于或等于给定值(x)的元素数 我的实现是这样的,但它是O(n) for(a=i;a=x)//p[]是包含n个元素的数组 计数++; 如果对数组进行排序,则可以通过二进制搜索找到小于X的第一个值,大于X的元素数是该元素之后的项数。那就是O(log(n)) 如果数组未排序,则无法在少于O(n)的时间内进行排序,因为您必须检查每个元素,以检查其是否大于或等于X。如果允许您对数组进行预处理,则使用O(n log

给定一个包含
n个元素的数组,如何在
O(logn)
中的
索引i到索引j
复杂度更好的
范围内找到大于或等于给定
值(x)
元素数

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

for(a=i;a=x)//p[]是包含n个元素的数组
计数++;

如果对数组进行排序,则可以通过二进制搜索找到小于X的第一个值,大于X的元素数是该元素之后的项数。那就是O(log(n))


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

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

两个想法:

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

2) 使用一个持久的*平衡顺序统计二叉树,它维护树的n个版本,版本i是从版本i-1添加[i]形成的。要回答
查询([0,i],x)
,您需要查询版本i树中的元素数量
>x
(基本上是排名信息)。订单统计树允许您这样做


*:持久性数据结构是一个优雅的函数式编程概念,适用于不可变的数据结构,并具有高效的算法来构造它们。

鉴于您的需求,数据没有提前排序,并且在查询之间不断变化,O(n)是您希望达到的最佳复杂性,因为在不查看所有元素的情况下,无法计算大于或等于某个值的元素数

仔细想想,这相当简单:如果您不知道如何提前表示/排序,那么就无法避免检查范围中的每个元素以进行任何类型的搜索

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

所以这里的O(N)实际上没有什么问题。这是理想的选择,您正在考虑改变外部数据的整体性质,以便能够提前对其进行有效排序,或者进行微优化(例如:并行fors,以处理多线程的子范围,前提是这些线程足够大),以对其进行调优

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

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

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

其思想是,您不需要对数组进行排序,只需对包含x的部分进行分区,并在x是透视元素时停止。完成此过程后,所有元素x及以上都位于x的右侧。这与查找第k个最大元素的步骤相同

在上阅读一个非常类似的问题


需求索引i到j不是对问题引入任何复杂性的限制

如果对数组进行排序,则可以使用二进制搜索。根据定义,在排序数组中大于第一个匹配项的每个值都可以添加,而无需额外处理。@timrau不是这样ordered@ElliottFrisch但是如果我对数组进行排序,索引i,j之间的元素会有所不同,您是否可以先对数组进行预处理?@ProgrammerPerson我得到了一个数组,然后给出了一些查询(i,j,x),我需要在(i,j)范围内为每个查询找到数量为greatan或等于x的元素。只有在有大量查询(x>>log(n))的情况下,才值得这样做,但如果事先对其进行排序,将比只检查
i
j
之间的所有内容更糟糕。拉尼兹:是的,这是真的<代码>x>日志(n)
并不是很大。例如,对于x=100万,我们讨论的是20多个查询。我需要将p[]
(i,j)范围内的元素与
x
进行比较,p[]包含
n
元素,并且该
(i,j,x)
集合对于同一数组p[]@polasairam:我想你是在谈论观察1)?我建议你考虑一下。。。(或者您的评论是针对Raniz的?在这种情况下,我建议您使用@feature…@polasairam:它是O(nlog n+K log n),其中K是查询数。先生,这里
x
可能包括在
数组p[]
中,也可能不包括在其中,
for(a=i;a<=j;a++)
    if(p[a]>=x) // p[] is array containing n elements
    count++;