Java中保留和删除ArrayList的时间复杂度是多少。

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. *

据我所知是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.
     *
     * @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
)。