Big-Oh使用list.retainAll的最坏情况是什么

时间:2015-02-11 01:40:46

标签: java list arraylist collections big-o

static List<String> common(String[] A, String[] B){
    Collection<String> listone = new ArrayList<String>(Arrays.asList(A));
    List<String> sorted = new ArrayList<String>(Arrays.asList(B));
    sorted.retainAll( listone );
return sorted;
}

我试过寻找API源代码;但我找不到list.retainAll方法的任何内容。

但我相信它是O(n)。这是对的吗?

2 个答案:

答案 0 :(得分:2)

答案取决于作为retainAll参数传入的集合类型。以下是Open JDK的实现:

public boolean retainAll(Collection<?> c) {
    boolean modified = false;
    Iterator<E> e = iterator();
    while (e.hasNext()) {
       if (!c.contains(e.next())) {
           e.remove();
           modified = true;
       }
   }
   return modified;
}

以下是删除为O(1)的情况的时间:

  • 如果c.contains(v)在O(1)中结束,则retainAll为O(N)。
  • 如果contains为O(Log M),则retainAll为O(N * Log M)。
  • 如果contains为O(M),则retainAll为O(N * M)。

如果您打算使用大型集合调用retainAll,并且性能至关重要,那么最好为要保留的列表构建HashSet。加速可能很重要。

Set<String> temp = new HashSet<String>(b);
a.retainAll(temp);

注意: ArrayList<T> has its own implementation of retainAll,它不会删除单个元素,将其想要保留的元素重写到列表的初始部分,以及然后在O(1)中一次性删除“尾部”元素。结合上面的HashSet<T>,这将为您提供一个时间为O(M + N)且空间为O(M)的算法。

答案 1 :(得分:0)

最糟糕的情况似乎是O(size A * size B)O(nm)。这是因为保留所有查看sorted中每个项目并将其与listone中的每个项目进行比较(使用迭代器)。

最糟糕的是,如果没有相似的项目,那么就会发生这种情况。但是,如果sorted中的所有项目都位于listone的迭代器的末尾,那么这也将近似于#{1}}。发生。