通过与另一个列表进行比较来从一个列表中删除重复项

时间:2013-04-08 23:58:34

标签: java algorithm list

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

e.g。我有两个列表,并假设每个字母代表对象。

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

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

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

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

你们能否建议用O(n)或小于O(n2)来解决这个问题。

我可以迭代这两个列表并通过比较删除重复的实例,但我希望有更高效的东西。

4 个答案:

答案 0 :(得分:6)

如果列表未排序,并且是ArrayLists或其他具有O(n)contains方法的类似列表实现,则应创建包含listB项的HashSet以执行删除。如果这些项目没有被置于一个集合中,那么你将获得O(n ^ 2)的表现。

因此,最简单的方法就是:

listA.removeAll(new HashSet(listB));

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

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

或者,如果对列表进行排序,则可以交替迭代它们。迭代通过ListA,直到你到达一个大于ListB当前元素的元素,然后遍历ListB,直到你到达一个大于ListA的当前元素的元素,等等。

答案 3 :(得分:0)

以下是在预期时间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