说我想存储字符串字典,我想知道是否存在某些字符串。我可以使用Trie或HashMap。 HashMap的时间复杂度为O(1),概率很高,而Trie在这种情况下的时间复杂度为O(k),其中k是字符串的长度。
现在我的问题是:不计算字符串的哈希值的时间复杂度为O(k),从而使HashMap的复杂性相同吗?如果没有,为什么?
我看到的方式是,这里的Trie比HashMap具有更低的时间复杂度来查找字符串,因为除了计算哈希值之外,HashMap可能会遇到冲突。我错过了什么吗?
更新: 在构造字典时,您将使用哪种数据结构来优化速度?
答案 0 :(得分:2)
除了执行trie的复杂性之外,还在确定哈希表中的桶的hashCode
方法的实现中进行了某些优化。对于java.lang.String
,一个不可变类,这是JDK-8的作用:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
因此,它被缓存(并且是线程安全的)。一旦计算,就不需要重新计算字符串的哈希码。这使您不必在哈希表(或哈希集,哈希映射)的情况下花费O(k)
时间。
在实施字典时,我认为尝试闪耀在你对可能的部分匹配而不是完全匹配更感兴趣的地方。一般而言,基于散列的解决方案在完全匹配的情况下效果最佳。
答案 1 :(得分:0)
在散列表上执行操作的时间复杂度通常以散列的数量来衡量,并且必须进行比较。在预期时,以这种方式测量的成本是O(1),因为在期望时只能使用恒定数量的散列和比较。
要确定为字符串使用哈希表的成本,确实需要考虑这些操作的成本,对于长度为k的字符串,每个操作的成本为O(k)。因此,对字符串的哈希表操作的代价是O(1)·O(k)= O(k),与特里成本相匹配,尽管只是在预期和不同的常数因子上。