java中的不替换拾取
我经常*发现自己需要具有以下属性的数据结构:java中的不替换拾取,java,data-structures,complexity-theory,montecarlo,picking,Java,Data Structures,Complexity Theory,Montecarlo,Picking,我经常*发现自己需要具有以下属性的数据结构: 可以用O(n)中的n个对象数组初始化 可以获得O(1)中的一个随机元素,在该操作之后,拾取 元素从结构中移除。 (无需更换) 可以撤消O(p)中的p“不替换拾取”操作 可以从O(log(n))中的结构中删除特定对象(例如通过id) 可以在中获取结构中当前的对象数组 O(n) 其他操作(如插入)的复杂性(甚至可能性)并不重要。除了复杂度外,它还应适用于少量的n 有谁能给我提供实施这种结构的指导方针吗?我目前实现了一个具有上述所有属性的结构,除了元素
- 可以用O(n)中的n个对象数组初始化
- 可以获得O(1)中的一个随机元素,在该操作之后,拾取 元素从结构中移除。 (无需更换)
- 可以撤消O(p)中的p“不替换拾取”操作
- 可以从O(log(n))中的结构中删除特定对象(例如通过id)
- 可以在中获取结构中当前的对象数组 O(n)
ArrayList
)怎么样?跟踪边界的位置,要拾取边界,需要在边界下方生成一个随机索引,然后(因为不关心顺序),将该索引处的项与最后一个未拾取的项交换,并减小边界。要取消拾取,只需增加边界
更新:忘记了删除O(日志(n))。不过,这并不难,只是内存有点贵,如果您保留索引的ID的HashMap
若你们在网上浏览,你们会发现各种各样的IndexedHashSet
实现或多或少都遵循这个原则——一个数组或ArrayList
加上一个HashMap
(不过,如果存在的话,我希望看到一个更优雅的解决方案。)
更新2:嗯。。。或者,如果必须重新复制阵列或将其四处移动,实际移除是否会再次变为O(n)?以下是我对在网络上使用的分析:
- ✔ 可以用O(n)中的n个对象数组初始化 是的,尽管成本是摊销的,除非事先知道n
- ✔ 可以获得O(1)中的随机元素,在此操作后,拾取的元素将从结构中移除,而无需更换
是,选择洗牌数组中的最后一个元素;用剩余元素的
子列表()替换数组
- ✔ 可以撤消O(p)中的p“不替换拾取”操作
是,通过
将元素追加到此列表的末尾add()
- ❍ 可以从O(log(n))中的结构中删除特定对象(例如通过id) 不,它看起来像O(n)
- ✔ 可以在O(n)中获得结构中当前的对象数组
是的,使用
看起来很合理toArray()
List<String> array = ArrayList<String>("abc","def","ghi")
List array=ArrayList(“abc”、“def”、“ghi”)
使用以下值创建HashMap映射:
for (int i = 0; i < array.size(); i++)
{
map.put(array[i],i);
}
for(int i=0;i
O(1)通过选取数组中的任何索引,可以轻松实现随机查找。唯一出现的复杂情况是删除对象时。为此,请:
地图中查找对象
。获取其数组索引。让我们调用这个索引i
(map.get(i)
)-O(1)map
(map.put(array[i],i))-O(1)中数组位置i
中新对象的索引我为java和cpp符号的混合表示歉意,希望这有助于我确实看到了如何使用hashmap实现除随机选取操作之外的所有操作。换句话说,如何从hashmap中选取随机元素?重新编辑:这不是O(1)选取(
collection.toArray()
始终至少是O(n)),而且它也不会从容器中移除选取的值。n、p和d的一些值是什么?一个非常有趣的结构。虽然不能保证移除是O(log(n)),但就我所见,移除是O(n)。它实际上类似于thrashgod的方法,但更有效,因为内存只分配一次。此外,如果索引了未粘贴的元素,则可以在O(1)中删除这些元素。@codelidoo:
List<String> array = ArrayList<String>("abc","def","ghi")
for (int i = 0; i < array.size(); i++)
{
map.put(array[i],i);
}