如何使用共享元素对列表进行聚类



这是我目前在Leetcode或StackOverflow上找不到的问题。假设您有一组数字或参考列表,如下所示:

[[1,2,3],[3,4,5],[6,7,8],[8,9],[10],[7]]

合并这些列表以使输出为:

[[1,2,3,4,5],[6,7,8,9],[10]]

非常感谢。

按如下方式从列表中准备一个图表,并使用深度优先搜索找到连接的组件。

每个列表都会产生将第一个元素连接到其他元素的无向边,例如,

[1,2,3] -> [(1,2), (1,3)]
[3,4,5] -> [(3,4), (3,5)]
[6,7,8] -> [(6,7), (6,8)]
[8,9]   -> [(8,9)]
[10]    -> []
[7]     -> []

然后运行深度优先搜索以查找连接的组件。在Python中,一切都是这样的。

import collections
def merge(lsts):
neighbors = collections.defaultdict(set)
for lst in lsts:
if not lst:
continue
for x in lst:
neighbors[x].add(lst[0])
neighbors[lst[0]].add(x)
visited = set()
for v in neighbors:
if v in visited:
continue
stack = [v]
component = []
while stack:
w = stack.pop()
if w in visited:
continue
visited.add(w)
component.append(w)
stack.extend(neighbors[w])
yield component

RosettaCode 有一个任务集合并,其中包含一个 Python 示例,可以修改该示例以处理列表:

def consolidate(lists):
setlist = [set(lst) for lst in lists if lst]
for i, s1 in enumerate(setlist):
if s1:
for s2 in setlist[i+1:]:
intersection = s1.intersection(s2)
if intersection:
s2.update(s1)
s1.clear()
s1 = s2
return sorted(sorted(s) for s in setlist if s)
print(consolidate([[1,2,3],[3,4,5],[6,7,8],[8,9],[10],[7]]))

输出:

[[1, 2, 3, 4, 5], [6, 7, 8, 9], [10]]

这实际上是一个聚类问题,而是一个集合联合问题。

通过名称">联合查找"或">脱节集",您可以找到一些经过充分讨论的方法来快速完成这些事情。

最新更新