684.冗余连接

https://leetcode-cn.com/problems/redundant-connection/

一、并查集

模板

class UnionFind:
    # 构造函数传入totalNodes为总节点数
    def __init__(self, totalNodes):
        # parents[i]表示i的根,初始i的根为其自身
        self.parents = [i for i in range(totalNodes+1)]
        # 连通分量数
        self.count = totalNodes
        # 连通分量大小,即树的“重量”
        self.size = [1] * (totalNodes+1)
    # 合并连通区域是通过find来操作的, 即看这两个节点是不是在一个连通区域内.
    def union(self, node1, node2):
        root1 = self.find(node1)
        root2 = self.find(node2)
        # 不连通才合并
        if root1 != root2:
          	# 小树合并到大树
            if self.size[root1] > self.size[root2]:
                self.parents[root2] = root1
                self.size[root1] += self.size[root2]
            else:
                self.parents[root1] = root2
                self.size[root2] += self.size[root1]
            # 连通分量数减一
            self.count -= 1

    # 查找最终的根
    def find(self, node):
        while self.parents[node] != node:
            self.parents[node] = self.parents[self.parents[node]]
            node = self.parents[node]
        return node

    # 判断两个点是否连通
    def isConnected(self, node1, node2):
        return self.find(node1) == self.find(node2)

    # 返回连通分量个数
    def count(self):
        return self.count

尝试每次删除一条边(edges中靠后的边),用剩下的边构建图,连接边的两顶点,若最后只构成一个连通分量,说明剩余的边可以构成树(题目已说明图是由树加一条边构成)

注意顶点从1开始,并查集实现稍作修改,留0号节点不用

class Solution:
    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        n = len(edges)
        for i in range(n-1, -1, -1):
            leftEdges = edges[:i] + edges[i+1:]
            uf = UnionFind(n)
            for a, b in leftEdges:
                uf.union(a, b)
            if uf.count == 1:
                return edges[i]

改进:逆向思维

上面方法是按题意正向操作,其实不需要每次都用n-1条边构建图。

现在反过来,按edges顺序遍历,每次测试两端点a、b是否连通,若不连通则将其连通;若已连通,说明增加这条边就构成图,该边就是要找的边

# 并查集实现代码同上,略
class Solution:
    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        n = len(edges)
        uf = UnionFind(n)
        for a, b in edges:
            if uf.isConnected(a, b):
                return [a, b]
            else:
                uf.union(a,b)

最后更新于