【问题标题】:Finding Overlapping Lists in a List of Lists在列表列表中查找重叠列表
【发布时间】:2019-08-18 05:29:57
【问题描述】:

我有一个列表列表,需要根据列表项的常见情况进行合并。共享元素的列表需要合并在一起形成集群。

我考虑过广度优先遍历来做这件事,但是由于列表列表的排列方式,很难实现遍历

列表示例:

input: 
[
 [1,2,3],
 [2,4,5],
 [4,6,8],
 [9,10,16],
 [16,18,19],
 [20,21,22]
]
output: [[1,2,3,4,5,6,8], [9,10,16,18,19], [20,21,22]]

前三个列表需要合并成一个列表(第一个列表和第二个列表有2个,第二个和第三个列表共享4个),第四个和第五个需要合并,因为两个共享16个。第三个是未与任何其他列表合并,因为它不与其他列表共享任何元素。

虽然这可以在 O(n^2) 时间内完成(n 是列表的数量),但我正在努力寻找最有效的方法。

【问题讨论】:

  • 内部列表是否总是排序([1,2,3])?是否还有其他我们需要注意的限制/规则?
  • 内部列表未排序。但是,在创建列表期间可以完成。没有与该问题相关的任何其他限制。
  • “很难实现遍历”,你是说你不是在寻找有图的解决方案,或者你接受它们但还没有找到简单的解决方案?
  • 可以将这些内部列表视为集合吗?它们似乎没有重复,并且存在使用集合执行此操作的代码。
  • 是的,没有重复

标签: python algorithm computer-science graph-algorithm


【解决方案1】:

您可以在 O(N * log N) 中执行此操作,其中 N 是所有列表中的项目总数。

使用Union Find数据结构的想法很简单:

  1. 首先让我们为输入中的每个唯一项创建 N 个不相交的集合
  2. 合并每个列表的所有相邻项的不相交集
  3. 从不相交的集合中收集结果

示例代码:

def Find(id,P):
    if P[id]<0 : return id
    P[id]=Find(P[id],P)
    return P[id]

def Union(id1, id2, p):
    id1 = Find(id1,P)
    id2 = Find(id2,P)
    if id1 != id2:
        P[id2]=id1

input=[
 [1,2,3],
 [2,4,5],
 [4,6,8],
 [9,10,16],
 [16,18,19],
 [20,21,22]
]

P = {}

for list in input :
    for item in list :
        P[item] = -1

for list in input :
    for i in range(1,len(list)):
            Union(list[i-1], list[i], P)

ans = {}
for list in input :
    for item in list :
        if Find(item,P) not in ans:
            ans[Find(item,P)] = []
        ans[Find(item,P)].append(item)

ans = [set(x) for x in ans.values()]
print(ans)

【讨论】:

  • 谢谢,这就是我要找的答案
【解决方案2】:

您的内部列表没有重复的元素。如果这是一般情况,那么 Rosetta Code 上的 set comsolidation 任务有一个可行的 Python 解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 2021-01-23
    • 2021-10-19
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    相关资源
    最近更新 更多