![](/img/trans.png)
[英]How do I efficiently count elements less than a certain value in a sorted array?
[英]TreeSet: number of elements less than a value efficiently
我需要一种方法来真正快速地计算出整数的TreeSet
中少于X的元素数。
我可以用
方法,但它们确实很慢(我只需要计数,而不是数字本身)。 有办法吗?
谢谢。
编辑:
我发现了一种变通方法,可以使事情更快! 我正在使用BitSet及其cardinality()方法。 我首先创建一个BitSet,然后为添加到TreeSet中的每个元素设置BitSet中的相应索引。 现在,要计算少于XI的元素数量,请使用:
bitset.get(0,X + 1).cardinality()
与treeset.subSet(0,true,X,true).size()相比,这要快得多。
有人知道为什么吗? 我假设BitSet.cardinality()不使用线性搜索。
“真正快速”需要多快? 您大致有多少个元素?
subSet()/headSet()/tailSet()
为O(1),因为它们返回原始树集的视图,但是如果您对您的subSet()
size()
,则您仍在遍历所有原始元素,因此O(N )。
您正在使用Java 8吗? 这将大致相同,但是您可以并行化成本。
Set<Integer> set = new TreeSet<>();
// .. add things to set
long count = set.parallelstream().filter(e -> e < x).count();
注意编辑
随着进一步的探索和试验,我不能证明的要求:“如果你size()
的subSet()
你还在遍历所有的原始元素”。 我错了。 在这4核机器上的parallelstream().count()
比subSet().size()
慢30%
如果您不更新数据结构,则只需在哈希图中使元素数少于X!
如果不经常更新,请保留一个排序的数字链接列表。 在插入/删除时,从O(1)中的列表添加/删除并更新哈希图(O(n))。
通过使用(排序的)二叉树,可以获取O(Log(n))和更新O(Log(n))。 在树的每个元素中,还保留其后代的数量。 现在,要获得#个项目<小于y,您可以在二叉树中找到它,而且无论何时右移而不是左移,都可以求和元素的数量。 在更新时,您还需要更新新元素的祖先。
顺便说一句,如果您愿意接受大概的答案,那么也可以有更快的方法。
由于到目前为止所有答案都指向与Java的TreeSet
不同的数据结构,因此我建议使用Fenwick树,该树具有O(log(N))用于更新和查询; 请参阅Java实现链接 。
package ArrayListTrial;
import java.util.Scanner;
public class countArray {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = new int[100];
Scanner scan = new Scanner(System.in);
System.out.println("input the number you want to compare:");
int in = scan.nextInt();
int count = 0;
System.out.println("The following is array elements:");
for(int k=0 ; k<array.length ; k++)
{
array[k] = k+1;
System.out.print(array[k] + " ");
if(array[k] > in)
{
count++;
}
}
System.out.printf("\nThere are %d numbers in the array bigger than %d.\n" , count , in);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.