你可以使用
不相交集合 的变体来解决这个问题:对于每个列表
[a,b,c]
,你需要将
a
与
b
和
a
与
c
进行
合并。你需要对两个列表都进行此操作,然后得到结果的根。
这里 有一个简单的
不相交集合算法,我们可以进行修改。
from collections import defaultdict
def parent(u,mapping):
if mapping[u] == u:
return u
mapping[u] = parent(mapping[u],mapping)
return mapping[u]
def relation(array,mapping=None):
if mapping is None:
mapping = {}
for e in array:
<b>if len(e) > 0:</b>
<b>u = e[0]</b>
if u not in mapping:
mapping[u] = u
<b>for v in e[1:]:</b>
if v not in mapping:
mapping[v] = v
mapping[parent(u,mapping)] = parent(v,mapping)
return mapping
def f(a,b):
<b>mapping = {}</b>
<b>relation(a,mapping)</b>
<b>relation(b,mapping)</b>
results = defaultdict(set)
for u in mapping.keys():
results[parent(u,mapping)].add(u)
return [list(x) for x in results.values()]
(加粗以突出与原始并集算法的语义差异).
这将产生:
>>> f(a,b)
[[2, 3], [4], [0, 1, 5], [6, 7], [8, 9, 10, 11], [12], [13, 14], [15]]
结果没有排序,因为我们使用了一个集合。不过,如果你想通过更改
f
来按每个元组的第一个元素轻松排序,那么你可以很容易地进行排序。
def f(a,b):
mapping = {}
relation(a,mapping)
relation(b,mapping)
results = defaultdict(set)
for u in mapping.keys():
results[parent(u,mapping)].add(u)
return <b>sorted(</b>[list(x) for x in results.values()]<b>,key=lambda t:t[0])</b>
这将产生:
>>> f(a,b)
[[0, 1, 5], [2, 3], [4], [6, 7], [8, 9, 10, 11], [12], [13, 14], [15]]
这个解决方案的好处是,即使在
a
或
b
本身存在
重叠,它也能正常工作,并且您可以轻松地将该解决方案推广到任意数量的列表(例如
a
,
b
和
c
)。
a
包含[1,2]
,[3,4]
,而b
包含[2,3]
,那么结果是否应该包含[1,2,3,4]
? - Willem Van Onsem[6, 7], [8, 9, 10, 11]
没有作为[6, 7, 8, 9, 10, 11]
出现在所需的输出中? - Moinuddin Quadri[7, 8]
),我就这样假设了。 - Ma0