在Java中开发,我需要一个数据结构来选择0到999999之间的N个不同的随机数?
我希望能够快速分配N个数字并确保它们不会重复。
主要目标不是使用太多内存并且仍然保持合理的性能。
我正在考虑使用BitSet但我不确定是否会影响内存。 有人能告诉我这个类的内存要求是否与位数或设置位数有关?设置/测试一下有多复杂?
更新: 感谢所有回复。
我认为我在这个Q的初始写法中有这个,但在我第一次看到BitSet类时删除了它。 无论如何,我想添加以下信息: 目前我正在寻找最多几千的N(最可能在1000-2000左右)和0到999999的数字范围。 但我希望我的选择考虑到将范围增加到8位(即0到99 999 999)同时将N保持在大致相同的范围(可能将其增加到5K或10K)的选项。 所以“使用过的价值”非常稀少。
答案 0 :(得分:4)
这取决于N
的大小。
对于N
的小值,您可以使用HashSet<Integer>
来保存已发出的数字。这样,您就可以O(1)
查找和O(N)
空间使用。
范围0-999999的BitSet
将使用大约125Kb,无论N
的值如何。对于足够大的N
值,这将比HashSet
更节省空间。我不确定N
的价值究竟是什么BitSet
会占用更少的空间,但我的估计会是10,000到20,000。
有人可以告诉我
BitSet
的内存要求是否与位数或设置位数相关?
大小由已设置的最大位确定,如果使用nBits
构造函数,则由BitSet(int nBits)
参数确定。
设置/测试一下有多复杂?
测试位B
为O(1)
。
设置位B
为O(1)
最佳情况,如果需要扩展位集支持数组,则设置为O(B)
。但是,由于后备阵列的大小是2的下一个最大功率,因此扩展成本通常可以在多个BitSet
操作中摊销。
答案 1 :(得分:0)
BitSet
将占用1,000,000布尔的空间,即125,000字节或大约122kB,加上一些小的开销和空间来增长。实数的数组,即int[]
将占用N×4B的空间加上一些开销。盈亏平衡点是
4 × N = 125,000
N = 31250
我并不熟悉Java内部,但我怀疑它不会分配超过实际使用空间的两倍,所以你使用的内存少于250kB。此外,当您需要唯一的整数时,数组会更难找到重复项,因此我会以任何一种方式使用bitset,如果更方便进一步处理,可能会将其转换为数组。
在BitSet
中设置/获取一点将具有不变的复杂性,尽管比从boolean[]
中获取一个操作需要更多的操作。