我有一套物品。集合中的每个项目可以与一个或多个其他项目相关。我想构建一种算法,将直接或通过其他项目相关的项目分组。
示例: 我的设置是{a,b,c,d,e,f}
a和b是相关的。 c与d有关,d与e有关。
该算法应生成以下组: {a,b},{c,d,e},{f}
有效算法的任何想法吗?在此先感谢: - )
答案 0 :(得分:8)
使用Union Find。它的速度非常快。使用路径压缩,复杂度降低到O(a(n)),其中a(n)是Ackermann函数的反函数。
答案 1 :(得分:3)
稍微扩展st0le的答案......
所以你有一个元素列表:
a,b,c,d,e,f
关系列表:
A-B
C-d
d-E
将每个元素放在自己的组中进行初始化。
然后,迭代你的关系列表。
对于每个关系,查找每个元素所属的组,然后联合这些组。
所以在这个例子中:
1: init -> {a}, {b}, {c}, {d}, {e}, {f}
2: a-b -> {a,b}, {c}, {d}, {e}, {f}
3: c-d -> {a,b}, {c,d}, {e}, {f}
4: d-e -> {a,b}, {c,d,e}, {f}
您显然必须检查所有关系。根据您实现“查找”部分的方式,这将影响算法的效率。所以你真的想知道在一组元素组中找到元素的最快方法是什么。一个天真的方法将在O(n)中做到这一点。您可以通过记录给定元素所在的组来改进这一点。然后,当然,当您联合两个组时,您将不得不更新您的记录。但这仍然有用,因为您可以将较小的组统一到较大的组中,这可以节省您需要更新的记录数。