是否可以在恒定时间内在集合中找到随机元素?

时间:2018-10-20 12:35:48

标签: algorithm hashmap time-complexity hashset

因此,我遇到了一个使用getRandomElement()函数构建集合的问题。乍看之下很容易。但是,我考虑的越多,我认为在O(1)时间复杂度上实现此目标的可能性就越小。没有固定时间的要求,但是所有主要功能集都是固定时间的,所以我觉得这暗示着也应该在固定时间内完成。

集合的目标是使用散列函数来减少冲突。现在的问题是,如果仅生成随机整数并尝试使用该随机整数选择索引,则很可能会遇到集合中的“空”槽。...在这种情况下,您必须生成一个新的随机数然后再试一次。本质上,您的哈希函数越好,使用这种方法执行的getRandomElement效果就越差。

那么我想...好吧,为什么不在每次插入后存储索引?然后,生成一个随机数并从该索引集合中选择一个索引。我以为这是个好主意,但随之而来的是删除元素的问题。我们还必须从索引列表中删除相应的索引,以及从Set中删除元素本身。我们如何找到正确的索引以比线性时间更快地删除它?

无论如何,从一组FEELS中获得一个随机元素比在线性时间内做得更好。顺便说一句,我正在通过链接处理碰撞。我不想浪费时间尝试做一些数学上不可能的事情,但是我也不是数学家,并且我不想放弃实际上可能的事情。

1 个答案:

答案 0 :(得分:5)

是的,可以构建一个支持O(1)getRandomElement操作的类似集合的数据结构。您将元素存储在数组中是正确的。删除元素的问题不太困难。

秘密是一旦孔的数量太大(例如,超过阵列大小的一半)就压缩阵列。这样,摊销的删除时间仍为O(1)。

执行getRandomElement()时,只需重复一次,直到击中实际元素为止。平均重复次数不超过2,因为该数组始终至少至少是半满的,因此您仍然拥有getRandomElement()的O(1)平均时间。

编辑:删除元素的一种更简单的方法可能是将最后一个元素移到腾出的位置。