使用python

时间:2018-02-19 19:41:53

标签: python list class partitioning equivalent

如果给出了两个数字列表,那么检测等效类的快速(est)方法是什么。

对于列表list1 = [1,1,2,3,3,4]list2 = [5,6,7,7,8,6] 应该是两个等价的类:eqClasses = [[1,4,5,6],[2,3,7,8]]

2 个答案:

答案 0 :(得分:1)

您可以使用union-find or disjoint set algorithm。 (我总是在附近有一个实现,因为它非常有用。)只是" union"不同的压缩数字对然后得到"组"那些具有相同"领导者"。

的数字

与问题无关的实施:

class UnionFind:
    def __init__(self):
        self.leaders = collections.defaultdict(lambda: None)

    def find(self, x):
        l = self.leaders[x]
        if l is not None:
            l = self.find(l)
            self.leaders[x] = l
            return l
        return x

    def union(self, x, y):
        lx, ly = self.find(x), self.find(y)
        if lx != ly:
            self.leaders[lx] = ly

    def get_groups(self):
        groups = collections.defaultdict(set)
        for x in self.leaders:
            groups[self.find(x)].add(x)
        return list(groups.values())

应用:

list1 = [1,1,2,3,3,4]
list2 = [5,6,7,7,8,6]

uf = UnionFind()
for a, b in zip(list1, list2):
    uf.union(a, b)

print(uf.get_groups())
# [{8, 2, 3, 7}, {1, 4, 5, 6}]

答案 1 :(得分:0)

在您的情况下,如果两个元素出现在同一位置的两个数组中,则它们是等效的。

如果你重新解决问题,那就归结为找到连接的子图。您可以将两个列表转换为等效数字对的列表。每个数字都可以视为图形中的顶点,每对数字都定义它们之间的边。可以使用简单的广度或深度优先搜索来查找连接的子图。 Wikipedia说:

  

在任何一种情况下,从某个特定顶点v开始的搜索都会在返回之前找到包含v(而不是更多)的整个连通组件。要查找图形的所有连通分量,请遍历其顶点,每当循环到达尚未包含在先前找到的连通分量中的顶点时,开始新的宽度优先或深度优先搜索。

如果您需要实用的解决方案,可以使用提供这些算法的软件包。看看NetworkX