Java中保留和删除ArrayList的时间复杂度是多少。
据我所知是O(n^2)还是Java中保留和删除ArrayList的时间复杂度是多少。,java,algorithm,time-complexity,Java,Algorithm,Time Complexity,据我所知是O(n^2)还是 /** * Retains only the elements in this list that are contained in the * specified collection. In other words, removes from this list all * of its elements that are not contained in the specified collection. *
/**
* Retains only the elements in this list that are contained in the
* specified collection. In other words, removes from this list all
* of its elements that are not contained in the specified collection.
*
* @param c collection containing elements to be retained in this list
* @return {@code true} if this list changed as a result of the call
* @throws ClassCastException if the class of an element of this list
* is incompatible with the specified collection
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the
* specified collection does not permit null elements
* (<a href="Collection.html#optional-restrictions">optional</a>),
* or if the specified collection is null
* @see Collection#contains(Object)
*/
public boolean retainAll(Collection<?> c) {
return batchRemove(c, true, 0, size);
}
boolean batchRemove(Collection<?> c, boolean complement,
final int from, final int end) {
Objects.requireNonNull(c);
final Object[] es = elementData;
int r;
// Optimize for initial run of survivors
for (r = from;; r++) {
if (r == end)
return false;
if (c.contains(es[r]) != complement)
break;
}
int w = r++;
try {
for (Object e; r < end; r++)
if (c.contains(e = es[r]) == complement)
es[w++] = e;
} catch (Throwable ex) {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
System.arraycopy(es, r, es, w, end - r);
w += end - r;
throw ex;
} finally {
modCount += end - w;
shiftTailOverGap(es, w, end);
}
return true;
}
/**
*仅保留此列表中包含在中的元素
*指定的集合。换句话说,从该列表中删除所有
*未包含在指定集合中的元素。
*
*@param c集合包含要保留在此列表中的元素
*@return{@code true}如果此列表因调用而更改
*如果此列表中某个元素的类
*与指定的集合不兼容
* ()
*如果此列表包含null元素且
*指定的集合不允许空元素
* (),
*或者如果指定的集合为空
*@see Collection#contains(对象)
*/
公共布尔保留(集合c){
返回batchRemove(c,true,0,size);
}
boolean batchRemove(集合c、布尔补码、,
最终整型起点,最终整型终点){
对象。要求不完整(c);
最终对象[]es=元素数据;
INTR;
//优化幸存者的初始运行
for(r=from;;r++){
如果(r==结束)
返回false;
如果(c)包含(es[r])!=补码
打破
}
int w=r++;
试一试{
对于(对象e;r
假设我们的ArrayList
有n
元素,而集合
有r
元素
答案取决于c.contains(es[r])
检查的时间,如在集合的子类中实现的:
- 如果
c
是另一个ArrayList
,那么复杂性实际上是二次O(n*r),因为c.contains(es[r])
是O(r)
- 如果
c
是一个TreeSet
则时间复杂度变为O(n*log2r),因为c.contains(es[r])
是O(log2r)
- 如果
c
是HashSet
则时间复杂度变为O(n),因为基于hash的c.contains(es[r])
是O(1)
实际上它取决于c
的集合实现。关键点是算法中的c.contains(…)
调用。您需要遍历所有您自己的元素,但是在这个包含方法中发生了什么
让我们看看最好和最坏的情况:
最佳案例(哈希集)
查找发生在O(1)中,因为元素是通过其哈希值存储的
由于必须检查ArrayList
中的所有元素,因此您得到了运行时O(n)(n是列表中元素的大小)
最坏情况(LinkedList)
查找发生在O(m)(LinkedList中的m个元素计数)中
因此,对于n中的每个元素,您需要在您得到的LinkedList中查找元素O(nm)。从ArrayList
中删除元素需要O(n)个时间,因为您必须将它后面的所有元素移向开始位置,以填补您创建的空白
retainal
和removeAll
但是,不要使用该过程删除每个元素。写入它们是为了在一次通过它们数组的过程中执行所有所需的移位
当它们穿过阵列时,要保留的图元将沿着任何删除操作所创建的间隙向前移动,从而将间隙移向阵列的末端。将忽略要删除的元素,从而导致间隙增大
由于这只需要通过数组一次,无论您必须删除多少个元素,如果引用集合可以在O(1)中执行contains()
,那么这些方法也会在O(N)时间内工作。对于数组列表,单个删除是O(N)
,因此执行m
次将导致O(nm)
我想说我确实指定了我对ArrayList感兴趣:)但你给出的答案是肯定的:)@Adelin这里有两个集合-一个是我们正在阅读的Retainal
(即此
),第二个作为参数传递给它。虽然this
始终是ArrayList
,Collection
可以是实现相应接口的任何东西。“二次O(n*r)”-O(n*r)
不是二次的(除非n==r
)。