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)。这是对的吗?
答案 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}}。发生。