首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >N集最大相交

N集最大相交
EN

Stack Overflow用户
提问于 2015-11-05 15:44:32
回答 3查看 910关注 0票数 13

我有x个集合,每个集合中都有y元素(未排序整数)。我想找出这两个集合之间相交的最大大小。

例如:

*5套,尺寸=3 1:1 2 3 集合2:4 2 3 一套3:5 6 7 一套4:5 8 9 一套5:5 10 11

最大相交集1与集合2,其大小为2;答案为2。

因此,我可以使用HashSets在O(x^2 * y)中完成,只需查找所有对并计算它们的相交大小。但我想快点。我认为有一些具体的算法或数据结构可以提供帮助。你能给我点主意吗?

UPDATE:X和y约为10^3,元素为int。也没有相等的集合。

EN

回答 3

Stack Overflow用户

发布于 2015-11-05 16:53:47

我能想到的一个优化是记住第一组和其他集合之间的交集大小,然后使用数据来切割一些情况。

如何使用它:

如果设置为ABC of length n

代码语言:javascript
复制
intersection(A,B) = p
intersection(A,C) = q

然后

代码语言:javascript
复制
intersection(B,C) <= n - abs(p - q)

对于您的案例中的集合:

代码语言:javascript
复制
S0 = { 1 2 3 }
S1 = { 4 2 3 }
S2 = { 5 6 7 }

计算intersection(S0,S1) = 2并记住结果:

代码语言:javascript
复制
[ i(0,1)=2 ]

然后是intersection(S0,S2) = 0,所以

代码语言:javascript
复制
[ i(0,1)=2; i(0,2)=0 ]

当您在比较第一个元素之后计算intersection(S1,S2)

代码语言:javascript
复制
(S1[0]=4 != S2[0]=5)

您可以说,intersection(S1,S2) <= 2是迄今为止最好的结果。

可以进一步改进的是记住更精确的交叉口结果,但仍然不能计算所有的结果。

我不确定这是不是最好的选择。也许有完全不同的方法来解决这个问题。

票数 4
EN

Stack Overflow用户

发布于 2015-11-05 17:04:42

下面是一些psuedocode:

代码语言:javascript
复制
function max_intersection(vector<vector<int>> sets):
    hashmap<int, vector<set_id>> val_map;
    foreach set_id:set in sets:
        foreach val in set:
            val_map[val].push_back(set_id);
    max_count = 0
    vector<int> counts = vector<int>(size = sets.size() * sets.size(), init_value = 0);
    foreach val:set_ids in val_map:
        foreach id_1:set_id_1 in set_ids:
            foreach id_2:set_id_2 in set_ids where id_2 > id_1:
                count = ++counts[set_id_1 * sets.size() + set_id_2];
                if (count > max_count):
                    max_count = count;
    return max_count;

因此,如果X是集合的数量,而Y是每个集合中的元素数:

  1. 插入val_mapO(X*Y)
  2. 创建counts并将每个元素初始化为零是O(X^2)
  3. 如果没有交叉点(每个值正好发生一次),那么最后一个循环将在time O(X*Y)中运行。但是,在另一个极端,如果有大量的交叉点(所有集合都是等价的),那么最后一个循环在O(X^2*Y)中运行。

因此,根据交叉口的数量,时间复杂度介于O(X*Y + X^2)O(X^2*Y)之间。

票数 4
EN

Stack Overflow用户

发布于 2015-11-05 17:09:09

我想不出一种改进O(x*x*y)的解决方案,但我可以建议一种避免散列的方法,而不是预期的复杂性 O(x*x*y),而是以增加10^6内存为代价的复杂性O(x*x*y)。查看您提供的约束,您将不超过10^6不同的数字。因此,我的想法是:对所有数字进行排序,然后将它们唯一(删除重复项)。将唯一编号从1到10^6(或唯一编号的数目)分配给每个数字(使用排序和唯一数组中的顺序)。在此之后,不要对每对都使用散列映射,而是使用10^6大小的位集。这样,您将有一定的O(x*x*y)复杂性(因为我建议的预计算是复杂度O(x * y *(log(x) + log (y)))。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33548896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档