【问题标题】:Is it possible to find a random element in a Set in Constant time?是否可以在恒定时间内在集合中找到随机元素?
【发布时间】:2019-03-25 03:11:54
【问题描述】:

所以,我遇到了一个使用 getRandomElement() 函数构建集合的问题。乍一看很容易。但是我越想这个,我就越觉得不可能在 O(1) 时间复杂度内做到这一点。对恒定时间没有给定要求,但所有集合的主要功能都是在恒定时间内完成的,所以我觉得它暗示这也应该在恒定时间内完成。

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

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

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

【问题讨论】:

  • 不太清楚你的问题是什么。 使用 getRandomElement() 函数构建集合 究竟需要什么?展示一些(伪)代码并解释它的行为如何不令人满意。
  • 我不一定有问题。我的问题本质上是可以比线性时间更快地完成随机元素。我真的不需要代码,或者问题的编码解决方案。
  • 所以你想从给定的集合中获取一个随机元素,而不是用任何东西构建一个集合。那是一个正确的措辞吗?
  • 所以我们可以随心所欲地构建这个集合。它只需要支持集合的基本功能,还需要有一个 getRandomElement 函数。从理论上讲,您应该能够插入、删除等。getRandomElement 应该从先前插入的集合中返回一个随机元素。
  • 哦,您想构建一个支持集合操作和 getRandomElement 操作的数据结构,速度比线性时间快,对吗?

标签: algorithm hashmap time-complexity hashset


【解决方案1】:

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

秘诀是一旦洞的数量太大(比如超过数组大小的一半)就压缩数组。这样摊销的删除时间仍然是 O(1)。

当执行getRandomElement() 时,只需重复,直到你碰到一个实际的元素。平均重复次数不超过 2,因为数组总是至少半满,所以 getRandomElement() 的平均时间仍然是 O(1)。

编辑:也许更简单的删除元素的方法是将最后一个元素移动到空出的地方。

【讨论】:

  • 啊,好的。是的,这完全有道理。我在尝试减少碰撞时过度优化,但即使如此,平均重复次数仍然是恒定的。不知道为什么这超出了我的想象,或者为什么我认为在“空”插槽的情况下生成另一个随机数会让我走上一条无穷无尽的生成随机数的道路,哈哈。谢谢!
猜你喜欢
  • 2019-07-23
  • 2016-11-12
  • 2016-08-12
  • 2021-08-18
  • 2018-07-02
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
相关资源
最近更新 更多