Ani*_*udh 14 java big-o hashset
例如,在下面的代码中:
public int commonTwo(String[] a, String[] b)
{
Set common = new HashSet<String>(Arrays.asList(a));
common.retainAll(new HashSet<String>(Arrays.asList(b)));
return common.size();
}
Run Code Online (Sandbox Code Playgroud)
让我们仔细阅读代码.该方法retainAll
继承自AbstractCollection
(至少在OpenJDK中)如下所示:
public boolean retainAll(Collection<?> c) {
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
Run Code Online (Sandbox Code Playgroud)
这里有一个很重要的事情,我们循环this.iterator()
并打电话c.contains
.所以时间复杂度是n
将呼叫c.contains
,其中n = this.size()
,最多n
调用it.remove()
.
重要的是该contains
方法在另一方面 被调用Collection
,因此复杂性取决于另一方的复杂性Collection
contains
.
所以,同时:
Set<String> common = new HashSet<>(Arrays.asList(a));
common.retainAll(new HashSet<>(Arrays.asList(b)));
Run Code Online (Sandbox Code Playgroud)
将是O(a.length)
,既然HashSet.contains
又HashSet.remove
是O(1)
(摊销).
如果你打电话
common.retainAll(Arrays.asList(b));
Run Code Online (Sandbox Code Playgroud)
然后,由于O(n)
contains
在Arrays.ArrayList
此将成为O(a.length * b.length)
-通过花费即O(n)
数组复制到HashSet
您实际拨打电话来retainAll
要快得多.
就空间复杂性而言,不需要额外的空间(超出Iterator
)retainAll
,但是当你分配两个HashSet
实际完全成熟的新实现时,你的调用实际上是非常昂贵的空间HashMap
.
还可以注意到另外两件事:
HashSet
从元素中分配一个a
- 一个更便宜的集合,也O(1)
可以从中间删除,如LinkedList
可以使用.(内存更便宜,也可以构建时间 - 不构建哈希表)b.size()
.