![](/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.