给定一组正整数< = k及其n个子集,找到哪些子集对给出原始集合的并集

时间:2017-06-05 09:13:03

标签: c++ algorithm set

我有一个集合A,它由第一个p正整数(1到p)组成,我给出了这个集合的n个子集。如何找到union上有多少对子集给出原始集A?

当然,这可以通过检查每对的并集的大小来天真地完成,如果它等于p,则union必须构成集合A,但是有更优雅的方式来做到这一点,这会减少时间的复杂性?

c ++中的set_union的时间复杂度为2*(size(set 1) + size(set 2)) - 1,这对nC2对不利。

2 个答案:

答案 0 :(得分:0)

如果我们需要应对最坏情况,那么关于这个问题的一些想法:

  1. 我认为在没有任何优化的情况下使用std::bitset对于此任务就足够了,因为联合操作要快得多。但如果没有,不要使用可变大小的向量,使用简单的p-length 0-1数组/向量或unordered_sets。我不认为没有O(1)查找操作的可变大小向量在最坏情况下会更好。

  2. 使用启发式方法最小化子集联合。最简单的启发式方法是检查子集的大小。我们只需要对(A, B)

  3. 的子集size(A) + size(B) >= p进行配对
  4. 除了启发式方法,我们还可以计算(O(n^2))子集中每个数字出现的频率。之后,我们可以按照频率增加的顺序检查某些子集中数字的存在。此外,我们可以排除每个子集中出现的数字。

  5. 如果您要修复某个子集A(例如在外部循环中)并找到包含其他子集的联合,则只能检查那些未出现在set {{ 1}}。如果子集A足够大,则可以显着减少所需的操作数。

答案 1 :(得分:0)

只是对您的方法进行了改进,而不是二进制搜索,您可以保留一个布尔数组,以确定 O中的某些 x 是否出现在 i 中(1)

例如, 让我们说,在进行输入时,您可以保存阵列 i 的所有外观。意思是,如果 x 出现在数组 i 中,则 isThere [i] [x] 应为true,否则为false。

这可以节省一些时间。