【问题标题】:Data structure in Java that supports quick search and remove in array with duplicatesJava中支持快速搜索和删除重复数组的数据结构
【发布时间】:2014-03-22 07:40:39
【问题描述】:

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

{3,2,3,4,2,2,1,4}

我希望有一个支持搜索的数据结构,并以比 O(n) 更快的速度删除某个值的第一次出现,假设该值为 4,那么它变成:

{3,2,3,2,2,1,4}

我还需要按照相同的顺序从头迭代列表。不需要 get(index) 或 insert 等其他操作。
您可以使用 O(n) 时间在您的数据结构中记录原始数据(比如说它是一个 int[]),我只需要稍后搜索和删除比 O(n) 更快。
如上所示,“搜索和删除”被视为 ONE 操作。
如果我必须自己制作,我会使用 LinkedList 来存储数据,并使用 HashMap 将每个键映射到所有出现的节点及其上一个和下一个节点的列表。
这是一个正确的方法吗? Java 中是否已有更好的选择?

【问题讨论】:

  • 如果它是一个未排序的输入数据,你永远不会比 O(n) 更好地删除重复项,因为你必须遍历每一个元素才能找到。
  • 你可以用 O(n) 时间来设置数据结构,我需要稍后搜索和删除才能更快。
  • 好的,如何获取一个Set,循环输入数据。如果整数不在 Set 中,则写入输出数组并将整数添加到 Set 中。最后,您将得到一个没有重复的输出数组,并保留顺序。
  • @anonymous 一般的Set 没有排序,并且没有任何 JRE 实现根据插入排序。
  • 我正在为您的实际问题写一个答案,但如果您描述了您正在完成的工作,可能会有更有效的方法来处理它。

标签: java data-structures hash linked-list duplicates


【解决方案1】:

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

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

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

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

【讨论】:

  • 感谢您的解释,首先分析代码是一个很好的建议。一开始我希望学习一些 Java 中的一些棘手的捷径,比如某种树数据结构?由于 O(log(n)) 也是受欢迎的。无论如何,我会选择你的答案。
  • 如果您提供使用散列的算法,那么您总是怀疑散列函数不属于通用散列函数系列。 @Bamqf 解释的算法的预期运行时间将是 O(1),不是吗?
【解决方案2】:

由于您的要求是应该删除第一次出现的元素并保留剩余的出现,因此没有办法比 O(n) 更快,因为您肯定必须移动到列表以查明是否还有其他事件。执行此操作的 java 包中没有来自 Oracle 的标准 api。

【讨论】:

  • 没有规定保留最后一次出现的元素。
  • 不,他已经明确提到需要消除第一次出现并提供了一个例子——据他说,最后一次出现需要保留
  • 第一个是的。 “保留最后一次出现”不会出现在问题中的任何地方
  • 嗯..从他的例子看来,这就是他想要的。也许他没有用完全相同的话说出来,但他的例子证明了这一点。
  • 不,他的示例演示了“删除第一个匹配项”。如果第一次出现是唯一的,那么它将被删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
  • 2012-10-02
  • 2014-09-24
  • 2018-10-12
  • 2011-07-14
  • 1970-01-01
相关资源
最近更新 更多