public void addOccurence(String word) {
if (hm.containsKey(word)){
hm.put(word, hm.get(word)+1);
}
else {hm.put(word, 1); }
}
我知道平均put(k,v)
和get(v)
取o(1)
,其最差的情况为o(n)
。那么containsKey(v)
呢?
以及如何确定以下内容的运行时间:
hm.put(word, hm.get(word)+1)
最差情况是o(n^2)
,平均o(1)
吗?
答案 0 :(得分:1)
最糟糕的是 O(N)。你正在进行两次或三次操作,每次操作都是 O(N),,所以你有< em> 3N 仍然是 O(N)。你没有做任何二次性的事情。
答案 1 :(得分:1)
hm.put(word, hm.get(word)+1)
的最差案例时间复杂度为O(N)
。
如何:假设您由于过度冲突而将hashMap转换为链接列表。因此get()
必须搜索整个链表O(N)
。类似地,hm.put()
将需要遍历链表以插入值。所以O(N)+O(N) = O(2N) ~ = O(N)
。
即使对于插入,您也不会遍历整个链表,因此get()
方法的时间复杂度为O(N)
。所以总数是O(N)
。因此,在这两种情况下,最坏情况的时间复杂度为O(N)
。
但同样的渐近下限为O(1)
。
如何:强>
因为如果您的密钥分布得很好,那么get()
的时间复杂度会o(1)
,insert
也会相同。因此导致渐近时间复杂度O(1)
。
答案 2 :(得分:1)
O(N)不是最坏的情况。 HashMap仅声称具有恒定的工作时间。事实上它不是真的。当特殊阈值超过时,通常通过重新划分Map来维持恒定的工作时间。看看内部HashMap方法:
void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
如果size大于阈值,则发生完全重新散列,其复杂性等于创建新的HashMap。所以最糟糕的情况是
如果你重写了hashCode()函数,那么可能会发生O(N),因此它具有纯粹的分布。在默认实现中,这种情况无法实现。唯一的危险就是重新开始。O(新的HashMap(oldMap))+ O(N)
答案 3 :(得分:0)
最坏的情况运行时不是O(n^2)
,因为你没有每个循环都有O(n)
RT的嵌套循环。运行时将是O(n),因为您要将hm.put(word, hm.get(word)+1)
方法的RT从hm.containsKey(word)
方法添加到RT。 O(n) + O(n) = O(2n)
==&gt; O(n)
最好的情况当然是如果字符串不在hashmap中并且else(...)
语句已执行,或O(1)
。
public void addOccurence(String word) {
if (hm.containsKey(word)){ //Worst Case O(n)
hm.put(word, hm.get(word)+1); //Worst case O(n)
}
else {hm.put(word, 1); } //O(1) Runtime
}
作为旁注,containsKey(k)
方法基本上是一个get(k)
方法,它根据密钥是否存在返回一个布尔值。另一方面,假设密钥存在于hashmap中,get(k)
方法实际上将返回密钥的值。两者的运行时间是相同的,因为它们基本上以相同的方式搜索hashmap。