从链表中删除集合的方法

时间:2018-10-10 17:04:07

标签: java methods collections linked-list hashset

我正在尝试一种方法,从链接列表“ L1”中删除集合“ L2”值的所有外观。我想知道如何去做。目前,我正在考虑从集合“ L2”的值中创建一个HashSet并将其删除,我只是想知道是否有一种方法可以使时间约束为O(n)。

忘记提及链接列表L1和集合L2均未排序。两者都是整数。

2 个答案:

答案 0 :(得分:1)

在元素的链表上调用int a = 24, int b = 3, int c = 12 : int d = 1 不是O(1);它开着)。因此,您的评估正确无误,即为remove的每个元素调用remove将为您提供O(mn)的运行时间。

要使整个删除过程为O(n + m),可以将值过滤到一个临时列表中,然后重建L1,但是您还需要为L2的元素设置一个集合,以便可以执行该操作过滤器检查O(1)时间。

L2

请注意,我们仅使用public static LinkedList<Integer> removeAll(LinkedList<Integer> L1, Collection<Integer> L2) { LinkedList<Integer> temp = new LinkedList<>(); HashSet<Integer> L2Set = new HashSet<>(L2); // O(m) // first filter elements into temp while (L1.size() > 0) { // n loops int v = L1.removeFirst(); // O(1) if (!L2Set.contains(v)) { // O(1) temp.addLast(v); // O(1) } } // add filtered values back to L1 while (temp.size() > 0) { // About n loops L1.addLast(temp.removeFirst()); // O(1) } return L1; } addLast,它们是O(1)运算,因此可以线性运行。

这还保留了removeFirst中元素的原始顺序。

答案 1 :(得分:1)

您可以在LinkedList.removeAll上使用L1,如果HashSet还不是L2,则将HashSet用于L1.removeAll(L2 instanceof HashSet ? L2 : new HashSet<>(L2));

L1

在更高级别上,此操作会迭代L2列表,并就地移除每个元素(如果它们属于另一个集合LinkedList.removeAll)。

在内部,Iterator使用其contains遍历其元素,然后使用另一个集合的contains方法检查是否应删除该元素。如果true返回Iterator.remove,它将通过Iterator.remove方法删除该元素。

现在,在LinkedList上使用O(1)contains最坏的情况,因为要删除的元素是迭代器当前指向的元素。并且在HashSet上使用O(1)O(n)的平均值,因此,如果L2已经是HashSet,则整个解决方案要么是O(n+m),要么是{ {1}}(如果没有)。 (此处n=L1.size()m=L2.size())。