假设您拥有一百万个手机号码记录库。您将如何存储这些数字,以便检查给定数字是否已经存在于最小的空间和时间复杂度中?
答案 0 :(得分:0)
根据最大电话号码数字d
,如果存在电话 i ,则可以使用位 i 为真的(大)位集:一个检查,你完成了。这将最小化时间复杂度,特别是如果你继续在一个机器上测试它,其中位集适合主存储器(尝试是O(数字) - 这将是O(1))。
如果您想最小化空间复杂性,10^d
>> n
(n =存储的手机数量),简单地将手机存储在排序的数组中将比构建传统的trie更紧凑(尝试有很多指针:开销)。二进制搜索仍然与使用trie在同一复杂度类别中(O(数字)是O(log n))。
另一种选择是构建bloom filters - 它们具有<强>空间优势而不是尝试,不涉及指针开销,并且通过构建正滤波器和负滤波器,您获得100 %精度和召回率。检索可能比其他选项慢一点,但从理论上讲,它仍然处于相同的复杂性类别。
像这样的问题有太多的摆动空间。如果没有更多细节,谈论“最佳”存储是没有意义的。此外,在95%的情况下,语言库提供的集合将足够好。 1M条目并不多。
答案 1 :(得分:0)
字典或哈希地图在这里非常好用。内存消耗为O(n),其中n是要存储的项目数。在.NET中,O(n)包含一个大约25左右的常量。因此,一百万个电话号码将需要大约25 MB的索引开销。但检查存在是O(1)。
对比一个特里,这可能是更多的内存饥饿(每个节点40个或更多字节),其查找时间是O(k),其中k是您正在查找的项目中的字符数。
尝试提供低技术解决方案也是值得的:一个简单的排序数组和一个二进制搜索。这将为您提供最小的内存占用,并且使用现代硬件可以快速地对一百万个项目进行二进制搜索。您没有说出您所需的吞吐量是多少,但如果您每秒进行大约一千次查询,则二进制搜索肯定符合要求。编写代码并对其进行分析可能值得您花些时间。如果简单的解决方案足够快,为什么选择“最快”?
答案 2 :(得分:-1)
使用Trie数据结构。 以下链接应该会有所帮助 http://www.codeproject.com/Articles/18033/Phone-Directory-Implementation-Using-TRIE