【问题标题】:Randomised Queue implementation - ideas for randomness随机队列实现 - 随机性的想法
【发布时间】:2020-09-19 00:03:32
【问题描述】:

我正在 coursera 中学习算法课程。其中一项作业如下:

随机队列。随机队列类似于堆栈或队列, 除了删除的项目是在项目中均匀随机选择的 在数据结构中。

我正在尝试找到一种在恒定时间内实现出队(随机删除项目)的方法。我想到了一个想法来做这个需要一个双端队列(它支持在恒定时间内从前面和后面删除和添加一个项目)。我的想法如下:

  • 使用双端队列作为随机队列中的底层数据结构
  • Enqueue - 使用库函数生成介于 0 和 1 之间的整数。如果整数为 0,则将该项目添加到双端队列的前面。否则,将其添加到后面。
  • 出队 - 任何方向都可以。

随机性发生在入队而不是出队中的原因是因为我发现它不是完全随机的(例如,对入队的 n 次调用将使出队仅返回第一个或第 n 个项目)。因此,为了确保这些项目被随机删除,我决定将它们随机排入队列。

这个想法对我来说似乎不错,因为我找不到其中的漏洞,但问题是我无法证明我的想法真的可行。我对随机性了解不多。事实上,这只是我第 5 次使用随机数据结构。

我的想法正确吗?它会生成一个随机删除项目的数据结构吗?

【问题讨论】:

    标签: algorithm random data-structures queue deque


    【解决方案1】:

    仅在末端排队不会产生均匀随机的序列。最后一个入队的项目必须在两端,而第一个入队的项目更有可能在中间的某个位置,而不是在其他项目入队后的两端。

    为了说明,以三个项目的集合{1, 2, 3} 为例,这是不会导致均匀分布的最小集合。按该顺序将它们加入队列会产生以下可能的结果(括号中是下一个项目加入队列的位置)。

    [1] -> (front) -> [1, 2] -> (front) -> [1, 2, 3]
    [1] -> (front) -> [1, 2] -> (back) -> [3, 1, 2]
    [1] -> (back) -> [2, 1] -> (front) -> [2, 1, 3]
    [1] -> (back) -> [2, 1] -> (back) -> [3, 2, 1]
    

    这四个结果是唯一的可能性,而且可能性均等。如您所见,最后一项永远不会在中间,而第一项和第二项都在中间两次。

    你想要的是在一个随机的地方出队。但是您不需要保留其他项目的顺序,因为它们是均匀分布的。这意味着您可以将最后一项与随机一项交换,然后将该一项(成为最后一项)出队。

    【讨论】:

      【解决方案2】:

      由于一致性要求,我认为您提出的方法行不通。一致性意味着队列中的每个项目都具有相同的出队可能性。您的提案总是将元素添加到一端,并从一端或另一端出列。因此,在任何给定的出队请求中,非结束元素被选中的概率为零。

      另一种方法可能是使用基于数组的堆栈。在堆栈的末尾添加元素,但为了出队随机选择一个元素,将其与最后一个元素交换,然后将其弹出。这将具有选择的一致性,并且所有的组件操作都是常数时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-02
        • 1970-01-01
        • 2019-09-19
        • 2017-01-27
        • 2011-07-03
        • 2015-09-17
        • 1970-01-01
        • 2012-07-17
        相关资源
        最近更新 更多