【发布时间】:2015-12-23 02:35:40
【问题描述】:
我需要一种方法来非常快地计算 TreeSet 的整数中小于 X 的元素数。
我可以使用
- 子集()
- headSet()
- tailSet()
方法,但它们真的很慢(我只需要计数,而不是数字本身)。有什么办法吗?
谢谢。
编辑:
我找到了一种使事情变得更快的解决方法!我正在使用 BitSet 和它的 cardinality() 方法。我首先创建了一个 BitSet,对于添加到 TreeSet 的每个元素,我在 BitSet 中设置了相应的索引。现在,要计算我使用的小于 X 的元素数:
bitset.get(0, X+1).cardinality()
这比 treeset.subSet(0, true, X, true).size() 快得多。
有人知道为什么吗?我假设 BitSet.cardinality() 不使用线性搜索。
【问题讨论】:
-
你可以试试 Guava
TreeMultiset,它支持headMultiset(element).size()在 O(log n),而不是 O(n)。不过,它与TreeSet不太一样。但是headMultiset(element).elementSet().size()也是 O(log n)。 -
为什么需要树集?您是否经常更新数据结构?如果您不更新数据结构,只需在 hashmap 中保持元素数量小于 X 即可!如果您不经常更新它,请保留一个排序的数字链接列表。在插入/删除时,在 O(1) 中从列表中添加/删除并更新哈希图 (O(n))。
-
感谢您的评论@Masood_mj。问题是 X 不是一个特定的值,每次我调用 cardinality() 函数时它都会改变。因此,如果我想使用哈希图,那么每次我将 Y 添加或删除到哈希图中(+1 或 -1 全部)时,我都必须使用 key > Y 更新所有项目。我错过了什么吗?
-
Hashmap+链表是 O(1) 获取和 O(N) 更新。通过使用(排序的)二叉树,您可以获得 O(Log(n)) 获取和 O(Log(n)) 更新。在树的每个元素中,还保留其后代的数量。现在要获得# items
-
好主意@Masood_mj,有没有办法在Java中拥有这样的二叉树或者我必须自己实现它?