【问题标题】:Removing duplicates from one list by comparing with another list通过与另一个列表进行比较从一个列表中删除重复项
【发布时间】:2013-03-31 05:48:15
【问题描述】:

我有两个对象列表,我想从另一个列表中的一个列表中删除实例。

例如我有以下两个列表,假设每个字母代表对象。

列表列表A = {A, B, C, D, E, F, G, H, I, J}

列表列表B= {D, G, K, P, Z}

现在,显然 listB 在 listA 上也有 D 和 G,所以我希望 listA 是这样的

listA = {A, B, C, E, F, H, I, J}

你们能否建议使用 O(n) 或小于 O(n2) 的解决方案。

我可以遍历这两个列表并通过比较删除重复的实例,但我想要更高效的东西。

【问题讨论】:

  • 你能假设列表已经排序了吗?
  • 没有。顺序无关紧要!
  • 有趣的是,第一个想法似乎总是排序,这当然是非常合理的,因为它允许线性复杂度的解决方案;但是一般来说,甚至不必在元素上存在偏序:)

标签: java algorithm list


【解决方案1】:

如果列表未排序,并且是 ArrayLists 或其他具有 O(n) 包含方法的类似列表实现,那么您应该使用 listB 的项目创建一个 HashSet 以执行删除。如果这些项目没有放入一个集合中,那么你最终会得到 O(n^2) 的性能。

因此,做你需要的最简单的方法是:

listA.removeAll(new HashSet(listB));

ArrayList.removeAll(Collection)不会为你把项目放入一个集合中(至少在我检查的JDK 1.6和1.7版本中),这就是为什么你需要在上面自己创建HashSet。

removeAll 方法将在遍历列表时将您希望保留的项目复制到列表的开头,从而避免每次删除时都会压缩数组,因此如图所示对传入的 HashSet 使用它是合理的最佳选择,并且是 O(n )。

【讨论】:

  • 这应该是一个可以接受的答案。优雅而简单。
  • 有趣!为什么不使用 HashSet 会导致 O(n^2)?我尝试搜索“数组压缩”,但无法从现有解释中弄清楚...
  • @DraxDomax O(n^2) 因为removeAll 通过迭代调用它的列表并在传入的每个元素的集合上调用contains 来工作。如果传入的集合是一个 ArrayList,那么它有一个 O(n) 包含方法,这就是我们最终得到 O(n^2) 的原因。现在,这并不完全准确,因为我们正在检查的集合可能具有有限的固定大小(例如 3 个元素或一些这样的元素),并且不能与另一个列表中的 N 一起缩放,因此这实际上取决于您的用例。更准确的说法是 O(n * j),其中 j 是传入集合的大小。
  • 我认为如果有更多的人认真思考编写循环的含义,那么现在使用软件会更有效:) 话虽如此,我可能没有工作因为我不是很好(虽然我尝试了!)。谢谢你的澄清!!!
【解决方案2】:

以下是要在预计时间O(n) 内解决的一些伪 C。

lenA = length pf listA
lenB = length of listB
shortList = (lenA <= lenB) ? A : B
longList  = (shortList == A) ? B : A

create hash table hashTab with elements of shortList

for each element e in longList:  
    is e present in hashTab:
        remove e from longList

now, longList contains the merged duplicate-free elements

【讨论】:

    【解决方案3】:

    您可以将两个列表元素都添加到 Set

    要从另一个列表中删除一个列表中的元素,请尝试listA.removeAll(listB);

    【讨论】:

    • 通过在 SET 中添加两个元素,我可以从列表中删除重复项。但我想将它从 listA 中完全删除。
    【解决方案4】:

    就像 ssantos 回答的那样,您可以使用 Set。

    或者,如果列表已排序,那么您可以交替地遍历它们。遍历 ListA 直到找到一个大于 ListB 的当前元素的元素,然后遍历 ListB 直到找到一个大于 ListA 的当前元素的元素,等等。

    【讨论】:

      猜你喜欢
      • 2018-02-19
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多