最近我在接受采访时被问到这个问题。我在O(n)时间给出了答案,但是两次通过。如果网址列表无法适应内存,他还问我如何做同样的事情。非常感谢任何帮助。
答案 0 :(得分:6)
如果这一切都适合内存,那么问题很简单:创建两组(选择您喜欢的数据结构),两者最初都是空的。一个将包含唯一的URL,另一个将包含多次出现的URL。扫描URL列表一次。对于每个URL,如果它存在于唯一集中,则将其从唯一集中删除并将其放入多个集中;否则,如果多重集中不存在,则将其添加到唯一集合中。
如果该组不适合内存,则问题很难解决。 O(n)的要求并不难以满足,但“单程”(似乎不包括随机访问等)的要求很难;如果没有数据限制,我认为这是不可能的。您可以使用具有集合大小限制的set方法,但是这很容易被数据的不幸排序所击败,并且无论如何只有一定的概率(<100%)找到唯一元素(如果存在)
编辑:
如果您可以设计一个存储在大容量存储中的集合数据结构(因此它可能比存储器中的大,并且可以在O(1)(摊销)时间内进行查找,插入和删除,那么您可以只需使用第一种方法来解决第二个问题。也许所有采访者都在寻找的是将URL转储到具有URL和计数列的UNIQUE索引的数据库中。
答案 1 :(得分:2)
可以尝试使用Trie结构来保存数据。它被压缩,因此它需要更少的内存,因为常见网址部分的内存重用。
循环看起来像:
add string s to trie;
check that added string is not finished in existing node
internal node -> compress path
leaf node -> delete path
答案 2 :(得分:0)
对于“适合内存”的情况,您可以使用以下两个哈希表(伪代码):
hash-table uniqueTable = <initialization>;
hash-table nonUniqueTable = <initialization>;
for-each url in url-list {
if (nonUniqueTable.contains(url)) {
continue;
}
else if (uniqueTable.contains(url)) {
nonUniqueTable.add(url);
uniqueTable.remove(url);
}
else {
uniqueTable.add(url)
}
}
if (uniqueTable.size() > 1)
return uniqueTable.first();
答案 3 :(得分:0)
基于Python
你有一个list
- 不知道它来自哪里,但是如果你已经在内存中那么:
L.sort()
from itertools import groupby
for key, vals in groupby(L, lambda L: L):
if len(vals) == 1:
print key
否则使用存储(可能使用):
import sqlite3
db = sqlite3.connect('somefile')
db.execute('create table whatever(key)')
获取数据,然后执行“从任意组中选择*,其中count(*)= 1)”
答案 4 :(得分:-1)
这实际上是一个经典的面试问题,他们期待的答案是你首先对网址进行排序,然后进行二元搜索。 如果它不适合内存,你可以用文件做同样的事情。