给定两个列表(不一定排序),最有效的非递归算法是什么,用于查找这些列表的交集?
我不认为我可以访问哈希算法。
给定两个列表(不一定排序),最有效的非递归算法是什么,用于查找这些列表的交集?
我不认为我可以访问哈希算法。
您可以将第一个列表的所有元素放入哈希集中。然后,迭代第二个列表,并针对其中的每个元素,检查哈希表以查看它是否存在于第一个列表中。如果是这样,请将其输出作为交集的一个元素。
您可能需要了解布隆过滤器。它们是位向量,能以概率性的方式回答一个元素是否为集合成员的问题。可通过简单的按位 AND 操作来实现集合交集。如果有大量的空交集,布隆过滤器可以帮助您快速消除这些情况。但是,您仍然需要采用这里提到的其他算法之一来计算实际的交集。
http://zh.wikipedia.org/wiki/布隆过滤器如果没有哈希,你大概有两个选择:
O(n + m)
,但并非总是可行的。 - Roman StarkovO(n lg n) * 2 + O(n) * 2
和 O(n lg n)
是相同的。 - porglezomp使用集合1构建一个二叉搜索树,时间复杂度为O(log n)
,然后迭代集合2并在二叉搜索树中搜索,时间复杂度为BST m X O(log n)
,因此总时间复杂度为O(log n) + O(m)+O(log n) ==> O(log n)(m+1)
在C++中,可以使用STL map尝试以下操作
vector<int> set_intersection(vector<int> s1, vector<int> s2){
vector<int> ret;
map<int, bool> store;
for(int i=0; i < s1.size(); i++){
store[s1[i]] = true;
}
for(int i=0; i < s2.size(); i++){
if(store[s2[i]] == true) ret.push_back(s2[i]);
}
return ret;
}
首先,使用快速排序算法对两个列表进行排序:O(n*log(n))。然后,通过先浏览最小值再添加共同值的方式比较这些列表。例如,在Lua中:
function findIntersection(l1, l2)
i, j = 1,1
intersect = {}
while i < #l1 and j < #l2 do
if l1[i] == l2[i] then
i, j = i + 1, j + 1
table.insert(intersect, l1[i])
else if l1[i] > l2[j] then
l1, l2 = l2, l1
i, j = j, i
else
i = i + 1
end
end
return intersect
end
这个算法的时间复杂度为O(max(n, m))
,其中n
和m
是列表的大小。