在作为特定集的子集的有限集合集中查找集合的最佳算法是什么?
例如,如果
A = {1, 2}
B = {2, 3, 4}
C = {3, 5}
D = {6}
和X = {1, 2, 3, 5}
然后,A和C是X的子集。
我是否可以使用线性时间复杂度进行算法?
实现注意事项:集合的成员通常来自非常有限的范围,因此,使用C ++ bitset实现算法可能是个好主意。不是吗?
编辑:集合中的集合数通常远大于X中的元素数(在示例中)。有没有办法在X中的元素数量方面做这个线性?可能使用哈希或什么?
答案 0 :(得分:7)
让我们暂时假设64个可能的元素。
然后,如果您将每个元素表示为一个位,则可以使用64位长的整数来表示每个集合,然后:a & b
是a
的{{3}}和{ {1}}。
如果(且仅当)b
是a
的子集,则b
。
当然,如果你需要64位以上,你可以使用bitset。
对于大范围的元素,使用哈希表存储(一次)超集,然后迭代潜在的子集以检查是否所有元素都在其中。
输入大小是线性的(平均情况)。
编辑:(对编辑问题的回复)
除非您预先存储了一些关于数据的信息 - 否则无法完成betetr然后a & b == a
其中| X |是集合X的大小,O(|X| + n*min{m,|X|})
是集合的数量,n
是集合的平均大小。
原因是因为在最坏的情况下,你需要读取所有集合中的所有元素(因为你为每个集合读取的最后一个元素决定它是否是一个子集),因此如果没有,我们就无法实现更好的目标先前对集合的了解。
建议的解决方案是:
比特集:m
哈希解决方案:O(|X|*n)
(平均情况)
虽然散列解决方案提供了更好的渐近复杂度,但是对于bitset来说常量要好得多 - 因此对于小O(|X| + min{m,|X|}*n)
答案 1 :(得分:1)
如果你没有时间建立一些额外的结构,O(log(n))解决方案将存储代表Trie个体集的位序列。
你不必将你的设置(a.k.a. bitstring)与Amit所设想的所有其他设置进行比较。如果你有一个排序的位串集合,那么每次比较显然会将变量的数量减少一半。是的,当然,构建bitset trie的时间类似于O(n * log(n)),但它是一个预处理。