Java中的数据结构,支持快速搜索和在数组中删除重复项

Java中的数据结构,支持快速搜索和在数组中删除重复项,java,data-structures,hash,linked-list,duplicates,Java,Data Structures,Hash,Linked List,Duplicates,更具体地说,假设我有一个重复的数组: {3,2,3,4,2,2,1,4} 我希望有一个数据结构,它支持搜索并以比O(n)更快的速度删除某个值的第一次出现,例如,如果该值为4,则它将变为: {3,2,3,2,2,1,4} 我还需要按照相同的顺序从head迭代列表。不需要执行get(索引)或insert等其他操作。 您可以使用O(n)时间在数据结构中记录原始数据(假设它是int[]),我只需要比O(n)更晚的搜索和删除速度。 “搜索和删除”被视为如上所示的一项操作。 如果必须自己制作,我会使用L

更具体地说,假设我有一个重复的数组:

{3,2,3,4,2,2,1,4}
我希望有一个数据结构,它支持搜索并以比O(n)更快的速度删除某个值的第一次出现,例如,如果该值为4,则它将变为:

{3,2,3,2,2,1,4}
我还需要按照相同的顺序从head迭代列表。不需要执行get(索引)或insert等其他操作。
您可以使用O(n)时间在数据结构中记录原始数据(假设它是int[]),我只需要比O(n)更晚的搜索和删除速度。
“搜索和删除”被视为如上所示的一项操作。
如果必须自己制作,我会使用LinkedList存储数据,使用HashMap将每个键映射到所有节点及其上一个和下一个节点的列表中。

这是正确的方法吗?Java中已经有更好的选择了吗?

因为您的要求是删除元素的第一个匹配项,保留其余的匹配项,所以没有办法比O(n)更快,因为您肯定必须移动到列表的末尾,以确定是否还有其他匹配项。java包中没有Oracle提供的标准api来实现这一点。

您描述的数据结构,本质上是一个混合的链表和映射,我认为是处理所述问题的最有效方法。您必须自己跟踪节点,因为Java的
LinkedList
不提供对实际节点的访问。
AbstractSequentialList
在这里可能会有所帮助

您需要的索引结构是从元素值到列表中该元素外观的映射。我推荐从
hashCode%module
到(值,主列表节点列表)的链接列表的哈希表

请注意,在最坏的情况下,当您有通用哈希冲突时,这种方法仍然是O(n);这适用于使用开放散列还是封闭散列。在一般情况下,它应该更接近O(ln(n)),但我不准备证明这一点


还要考虑一下跟踪所有这些的开销是否真的值得。除非您实际分析了正在运行的代码,并确定
LinkedList
会导致问题,因为
remove
是O(n),否则请坚持执行该操作,直到执行为止。

如果是未排序的输入数据,删除重复项的效果永远不会比O(n)好,因为您必须遍历每个元素才能找到答案。您可以使用O(n)设置数据结构的时间到了,我需要稍后搜索和删除以加快速度。好的,获取一个集合,循环输入数据。如果整数不在集合中,则写入输出数组并将整数添加到集合中。最后,您将得到一个无重复项的输出数组,并且保留顺序。@anonymous常规
集合
未排序,并且没有一个JRE实现是按照插入排序的。我正在为你的实际问题写一个答案,但是如果你描述了你正在完成的事情,可能会有一个更有效的方法来处理它。没有要求保留元素的最后一次出现。没有。他明确提到第一次出现需要消除并提供了一个例子——根据他的说法,最后一次发生的事件需要保留到第一次。“保留最后一次发生的事件”在问题的任何地方都没有出现。嗯……从他的例子来看,这似乎是他想要的。也许他没有用完全相同的话说出来,但他的例子证明了这一点。不,他的例子证明了“删除第一个事件”。如果第一次出现是唯一的一次,那么它将被删除。感谢您的解释,首先分析代码是一个很好的建议。首先,我希望了解Java中一些棘手的快捷方式,比如某种树数据结构?因为O(log(n))也是受欢迎的。无论如何,我会选择你的答案。如果你提供了一个使用哈希的算法,那么你总是怀疑hashfunction出自一系列univseral hashfunctions。那么@Bamqf解释的算法的预期运行时间将是O(1),不是吗?