Skip to the content.

leetcode [684] 冗余连接


Contact me:

Blog -> https://cugtyt.github.io/blog/index
Email -> cugtyt@qq.com
GitHub -> Cugtyt@GitHub


在本问题中, 树指的是一个连通且无环的无向图。

输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, …, N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。

结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。

返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。

示例 1:

输入: [[1,2], [1,3], [2,3]]
输出: [2,3]
解释: 给定的无向图为:
  1
 / \
2 - 3

示例 2:

输入: [[1,2], [2,3], [3,4], [1,4], [1,5]]
输出: [1,4]
解释: 给定的无向图为:
5 - 1 - 2
    |   |
    4 - 3

注意:

输入的二维数组大小在 3 到 1000。
二维数组中的整数在1到N之间,其中N是输入数组的大小。

来自题解:

使用并查集,每加入一组边,如果两个节点有相同的根节点,那么他们是多余的,否则设定一个节点的根节点是另一个节点。注意并查集的实现,查找的时候不断找根节点,如果根节点是-1。union的时候,查找两个节点的根节点,如果不相等,或者都为-1表示两个节点分别属于两棵树,表示可以联合,将一个节点作为另一个节点的根节点。如果相等,表示这条边已经有另外连通的边,即为冗余边。

class disjoint:
    def __init__(self, N):
        self.array = [-1] * N
        
    def find_root(self, i):
        while self.array[i] != -1:
            i = self.array[i]
        return i
    
    def union(self, i, j):
        i = self.find_root(i)
        j = self.find_root(j)
        if (i != j) or (i == -1 and j == -1):
            self.array[i] = j
            return j
        else:
            return -1

class Solution:
    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        nodes = set()
        for a, b in edges:
            nodes.add(a)
            nodes.add(b)
            
        dj = disjoint(len(nodes) + 1)
        
        answer = None
        for a, b in edges:
            x, y = dj.find_root(a), dj.find_root(b)
            if (x != y) or (x == -1 and y == -1):
                dj.union(a, b)
            else:
                answer = [a, b]
        
        return answer