Java 方法从链接列表中删除集合

Java 方法从链接列表中删除集合,java,methods,collections,linked-list,hashset,Java,Methods,Collections,Linked List,Hashset,我试图创建一种方法,从链接列表“L1”中删除集合“L2”值的所有外观。我想知道怎么做。目前我正在考虑从集合“L2”的值生成一个HashSet并将其删除,我只是想知道是否有一种方法可以生成时间约束为O(n)的方法 忘记提及Linkedlist L1和集合L2都未排序。两者都是整数。在链表上为元素调用remove不是O(1);它是O(n)。因此,您的评估是正确的,对L2的每个元素调用remove将为您提供一个O(mn)运行时间 要使整个删除过程成为O(n+m),您可以将值过滤到临时列表中,然后重建L

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


忘记提及Linkedlist L1和集合L2都未排序。两者都是整数。

在链表上为元素调用
remove
不是O(1);它是O(n)。因此,您的评估是正确的,对
L2
的每个元素调用
remove
将为您提供一个O(mn)运行时间

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

公共静态LinkedList removeAll(LinkedList L1,集合L2){
LinkedList temp=新建LinkedList();
HashSet L2Set=新的HashSet(L2);//O(m)
//首先,将滤芯装入温度传感器
而(L1.size()>0){//n个循环
int v=L1.removeFirst();//O(1)
如果(!L2Set.contains(v)){//O(1)
临时addLast(v);//O(1)
}
}
//将过滤后的值添加回L1
而(temp.size()>0){//n个循环
L1.addLast(temp.removeFirst());//O(1)
}
返回L1;
}
请注意,我们只使用了
addLast
removeFirst
,这是O(1)操作,为我们提供了一个线性运行时间


这还保留了
L1

中元素的原始顺序您可以使用
LinkedList。如果
L1
上的
哈希集还不是
L2
,请使用
HashSet
移除所有

L1.removeAll(L2 instanceof HashSet ? L2 : new HashSet<>(L2));
L1.removeAll(哈希集的L2实例?L2:新哈希集(L2));
在更高的级别上,这将迭代
L1
列表,并删除属于另一个集合
L2
的每个元素

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


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

linkedList.removeAll(someCollection)
?您的集合是否已排序?根据我收集的数据,算法O(n*n)集合和链接列表均未排序。那么您最好的方法是O(nlogn)不制作字典。是的
remove
在java中的链表上不是O(1),取消链接的
是。删除操作仍需在列表中搜索其所在的节点,然后调用
取消链接
。我删除了我以前的评论。很酷!我一直在IntelliJ中单击
Cmd+,直到在
java.util.AbstractCollection#removeAll
中找到这个实现。它确实调用了
It.remove()。
L1.removeAll(L2 instanceof HashSet ? L2 : new HashSet<>(L2));