假设您有两个整数集列表。将它们称为A和B. A中的每个集合都可以包含在B中的一个集合中。找到A中所有元素的最有效算法是什么,以便一组中没有包含B?
答案 0 :(得分:1)
为了尝试修剪搜索空间,我们可以尝试一些检查和过滤器作为搜索的一部分。在评论中举例说明,
A = [{1,2},{1,4},{3,4,7}]
B = [{2,3,4},{1,2,4},{1,2,5,6}]
从集合中唯一元素的O(n)枚举开始,作为指向它们所属集合的跨相关索引的键:
1: A: {0,1}, B: {1,2}
2: A: {0} , B: {0,1,2}
3: A: {2} , B: {0}
4: A: {1,2}, B: {0,1}
5: A: {} , B: {2}
6: A: {} , B: {2}
7: A: {2} , B: {}
我们可以立即在A中留出包含B中未找到的元素的集合,例如A的第三集。
现在,我们将遍历A中尚未排除的每个集合,并检查B中是否存在至少一个集合的相应完整交集。由于您的案例中的集合索引数量为数百万,而不是最初完全遍历B我们将把我们对B的检查分成几个部分,每个k
集合,比如1024.此外,为了表示这1024个集合索引,我们将它们分成16个64位集合每个位,所以我们可以按位 - 和(和)一个与另一个。
在此遍历期间的任何时候,如果AND操作导致零,我们将从提前退出中受益:
set A[0] => elements 1,2 => set-index-intersection in B: b110 & b111 => match
set A[1] => elements 1,4 => set-index-intersection in B: b110 & b11 => match
总的来说,逐节工作,我们正在查看大约10 * 16个操作,以检查A中的一个集合是否包含在k
B集的当前部分中的一个集合中。换句话说,我们已将操作次数从10,000,000减少到160,000,以便对A中的一组进行全面检查(B中每百万套)。这是62的因素。