我正在寻找构建一个数据结构,其中通过调用add()将数组填充在随机空位置。一旦一个位置被填满,它就不会被另一个add()覆盖。调用remove(i)释放A [i]处的位置。可以混合调用add()和remove()。
我的第一个想法是每次调用add()时随机生成0到n-1之间的数字。如果是空的,请填写;如果已满,请执行顺序搜索,直到找到空的搜索。然而,这有两个问题:1)如果阵列大部分已满,则接近O(n)时间2)随机选择将不均匀。
我的第二个想法是在数字1到n-1上使用shuffle并按此顺序添加,但是这不支持remove()。
有没有办法实现这个保证add()和remove()的持续性能?
答案 0 :(得分:0)
让我们调用要填充的数组work_array[]
。使用两个辅助数组,filled_positions[]
和empty_positions[]
,包含work_array[]
中的索引,以及两个计数器num_filled
和num_empty
,以filled_positions[]
中的元素数量1}}和empty_positions[]
。假设数组从0开始索引,最初num_filled
为0,empty_positions[]
包含0,1,2,...到 n - 1,num_empty
是 n 。
要在随机位置添加元素:
0
和num_empty - 1
之间生成一个随机数 r 。empty_positions[r]
num_empty
- 1,请将empty_positions[r]
设为empty_positions[num_empty-1]
。num_empty
。filled_positions[num_filled]
设为 i 。num_filled
。work_array[i]
填写元素。要从随机位置删除元素:
0
和num_filled - 1
之间生成一个随机数 r 。filled_positions[r]
num_filled - 1
,请将filled_positions[r]
设为filled_positions[num_filled-1]
。num_filled
。empty_positions[num_empty]
设为 i 。num_empty
。如果填充work_array_map[]
,则可能需要维护一个位数组work_array_map[i]
,其中work_array[i]
为1,否则为0。使用work_array_map[]
,您可以判断元素 i 是否在常量时间内填充。
答案 1 :(得分:-1)
您可以为填充和空数组位置保留一个单独的链接列表。现在生成0到(考虑链接列表的长度,即填充或空)的随机数,并使用它从列表中选择随机位置。 现在,如果从填充列表中选择任何元素,则删除相应的条目并将其添加到空列表中。 当然,链表的遍历将花费O(链表的长度)时间,但这消除了在add()时选择填充位置的问题或者在remove()时选择空位置的问题。