【问题标题】:Filling up an array randomly随机填充数组
【发布时间】:2017-06-04 23:11:26
【问题描述】:

我正在寻找通过调用 add() 在随机空位置填充数组的数据结构。一旦一个位置被填满,它就不能被另一个 add() 覆盖。调用 remove(i) 释放 A[i] 处的位置。可以混合调用 add() 和 remove()。

我的第一个想法是每次调用 add() 时随机生成一个介于 0 和 n-1 之间的数字。如果是空的,填满它;如果它已满,则进行顺序搜索,直到找到一个空的。然而,这有两个问题:1)如果数组大部分是满的,它将花费接近 O(n) 时间 2)随机选择将不均匀。

我的第二个想法是对数字 1 到 n-1 使用随机播放并按此顺序添加,但是这不支持 remove()。

有没有一种方法可以保证 add() 和 remove() 的持续性能?

【问题讨论】:

    标签: arrays algorithm performance random data-structures


    【解决方案1】:

    我们将要填充的数组称为work_array[]。使用两个辅助数组filled_positions[]empty_positions[],包含work_array[] 中的索引,以及两个计数器num_fillednum_empty,给出filled_positions[]empty_positions[] 中的元素数。假设数组从 0 开始索引,最初 num_filled 是 0,empty_positions[] 包含 0、1、2、... 到 n - 1,而 num_emptyn。

    • 在随机位置添加元素:

      1. 0num_empty - 1 之间生成一个随机数r
      2. empty_positions[r]中选择索引i
      3. 如果 r 小于 num_empty - 1,则将 empty_positions[r] 设置为 empty_positions[num_empty-1]
      4. 递减num_empty
      5. filled_positions[num_filled] 设置为i
      6. 递增num_filled
      7. work_array[i]处填充元素。
    • 从随机位置移除元素:

      1. 0num_filled - 1 之间生成一个随机数r
      2. filled_positions[r]中选择索引i
      3. 如果 r 小于num_filled - 1,则将filled_positions[r] 设置为filled_positions[num_filled-1]
      4. 递减num_filled
      5. empty_positions[num_empty] 设置为i
      6. 递增num_empty

    您可能想要维护一个位数组work_array_map[],如果work_array[i] 被填充,则work_array_map[i] 为1,否则为0。使用work_array_map[],您可以判断元素 i 是否在恒定时间内被填充。

    【讨论】:

      【解决方案2】:

      您可以为填充和空数组位置保留一个单独的链接列表。现在生成一个介于 0 到(考虑的链表长度,即填充或空)之间的随机数,并使用它从列表中选择一个随机位置。 现在,如果您从填充列表中选择任何元素,则删除相应的条目并将其添加到空列表中。 当然,链表的遍历将花费 O(链表的长度)时间,但这消除了在 add() 时选择填充位置或在 remove() 时选择空位置的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 2013-09-16
        • 1970-01-01
        • 2020-02-26
        • 2017-04-17
        相关资源
        最近更新 更多