【问题标题】:What data structure can achieve random pop and push in better than O(n) time?什么数据结构可以实现比O(n)时间更好的随机pop和push?
【发布时间】:2021-03-08 17:30:58
【问题描述】:

我正在尝试设计一种支持随机弹出和插入操作的数据结构。一个元素根据其权重随机弹出。例如,如果数据结构具有权重为“10”和“20”的元素“a”和“b”,则元素“b”被弹出的可能性是“a”的两倍。 n 是元素的数量。权重可以是浮点数或整数,为>=0

我认为段树或二叉索引树可能能够在 O(log n) 时间内实现这两种操作,但我不确定。谁有更好的主意?

【问题讨论】:

  • 你能把这个问题说得更准确一些吗?即 1. 指定 n 是什么(我假设数据结构中的元素数量)2. 指定权重的限制,例如“仅自然数 或 “仅来自预定义集合 {1, 2, 5} 的权重”。限制越多,解决方案可能越有效。 3. 只是为了确保:这不像是优先级队列,而更像是一个集合?例如。当您有 (a,1), (b,2), (c,2) 时,第一个弹出操作可能会以 2/(1+2+2) 的概率返回 c。这是正确的吗?
  • @Socowi 我刚刚添加了更多细节。对于你的第三个问题,是的,这是正确的。元素应该以它们的权重除以元素的总权重的概率被弹出。
  • 我建议在你的问题中避免使用“push”和“pop”这两个词,它们与堆栈的概念密切相关。命名法对于有效沟通很重要。

标签: algorithm data-structures


【解决方案1】:

order statistic tree 的变体应该能够做到这一点:拥有一个自平衡二叉搜索树,其中每个节点还存储其子树的总权重(标准版本将存储其基数)。

插入和移除已经在 O(log n) 时间内完成,也可以在 O(log n) 时间内获取加权随机样本:首先在 0 到整棵树的总权重,从根节点开始。设t为随机数,l为左子树的总权重(如果没有则为零),c为当前节点的权重:

  • 如果 t < l 则在左子树上递归。
  • 否则如果t - l < c则返回当前节点中的项目。
  • 否则从t 中减去l + c 并在右子树上递归。

【讨论】:

  • 我想这也是我所设想的。澄清一下,当您说“每个节点还存储其子树的总权重”时,子树的总权重还包括来自当前节点的贡献,对吧?
  • 是的,这绝对是两个操作的平均 O(log n) 之一,但如果我们正在寻找 O(log n) 最坏的情况,我们需要使用自平衡树。如果所有权重都在 [1,2] 内,是否有不同的方法可以让我们进行恒定时间操作?
  • 是的,它需要是一个自平衡的 BST,我已经编辑添加了它。在权重在 [1,2] 中的情况下,那么通过随机抽样然后翻转有偏的硬币来决定是保留它还是再拿一个,应该可以获得 O(1) 的预期时间;保留样本的概率应等于项目的权重除以 2。由于权重以正数(在本例中为 1)为界,因此预期的拒绝数是一个常数。我认为这是一个完全不同的问题和解决方案,您应该将其作为一个单独的问题发布。
  • 嗯,是的,我理解这种方法,但似乎假设权重只能是 12。当它说“以 [1,2] 为界”时,这是否意味着它可以是该区间内的任何实际值,例如 1.01、1.4、1.555555 等...?
  • 对于区间 [a,b] 中的任意实数权重,它应该可以工作(并给出正确的加权分布)。其中 0
猜你喜欢
  • 2019-10-23
  • 2018-11-05
  • 1970-01-01
  • 2011-05-04
  • 2012-05-09
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
  • 2015-11-17
相关资源
最近更新 更多