我经常发现自己需要一个具有以下属性的数据结构:
- can be initialized with an array of n objects in O(n).
- one can obtain a random element in O(1), after this operation the picked
element is removed from the structure.
(without replacement)- one can undo p ‘picking without replacement’ operations in O(p)
- one can remove a specific object (eg by id) from the structure in O(log(n))
- one can obtain an array of the objects currently in the structure in
O(n).
其他行为(例如插入)的复杂性(甚至可能性)无关紧要.除了复杂性之外,它对于少量的n也应该是有效的.
谁能给我指导实施这样的结构?我目前实现了一个具有上述所有属性的结构,除了元素的选择需要O(d)和d过去选择的数量(因为我明确检查它是否’尚未被选中’).我可以找出允许在O(1)中进行拾取的结构,但是这些结构在至少一个其他操作中具有更高的复杂性.
BTW:
请注意,上面的O(1)意味着复杂性与#earlier拾取的元素无关,并且与总的#elements无关.
*蒙特卡罗算法(从n个元素的’集’中迭代选择p个随机元素).
解决方法:
好的,与0verbose相同的答案,只需一个简单的修复即可获得O(1)随机查找.创建一个存储相同n个对象的数组.现在,在HashMap中,存储对.例如,假设你的对象(简单的字符串)是:
{"abc" , "def", "ghi"}
创建一个
List<String> array = ArrayList<String>("abc","def","ghi")
使用以下值创建HashMap映射:
for (int i = 0; i < array.size(); i++)
{
map.put(array[i],i);
}
通过选择数组中的任何索引,可以轻松实现O(1)随机查找.出现的唯一复杂因素是删除对象时.为此,做:
>在地图中查找对象.获取其数组索引.让我们调用这个索引i(map.get(i)) – O(1)
>使用array [size of array – 1](数组中的最后一个元素)交换数组[i].将数组的大小减少1(因为现在数量减少一个) – O(1)
>更新map中数组位置i中新对象的索引(map.put(array [i],i)) – O(1)
我为java和cpp表示法的混合道歉,希望这会有所帮助