跳转至

684. 冗余连接

题目描述

关联:https://leetcode.cn/problems/redundant-connection/description

题目描述

树可以看成是一个连通且 无环无向 图。

给定往一棵 n 个节点 (节点值 1n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1n 中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n 的二维数组 edgesedges[i] = [a_i, b_i] 表示图中在 a_ib_i 之间存在一条边。

请找出一条可以删去的边,删除后可使得剩余部分是一个有着 n 个节点的树。如果有多个答案,则返回数组 edges 中最后出现的那个。

范围:

  • \(n == \text{edges.length}\)
  • \(3 \leq n \leq 1000\)
  • \(\text{edges}[i].\text{length} == 2\)
  • \(1 \leq a_i < b_i \leq \text{edges.length}\)
  • \(a_i \neq b_i\)
  • \(\text{edges}\) 中无重复元素
  • 给定的图是连通的

解题思路

并查集秒了。

可以使用并查集(Union-Find)数据结构来解决在图中找到冗余连接的问题。并查集可以高效地管理和合并不相交的集合,并且可以用来检测无向图中的环。

步骤:

  1. 初始化并查集:创建一个父节点数组来跟踪每个节点的父节点,并创建一个秩数组来优化树的高度。

  2. 处理每条边:对于每条边,使用并查集检查这条边的两个节点是否已经连接。

    • 如果已经连接,说明添加这条边会形成环,因此这条边就是冗余边。

    • 如果没有连接,则将这两个节点合并。

  3. 返回冗余边:第一个形成环的边就是冗余边。

完整题解

UnionFind 类:管理并查集的合并和查找操作,使用路径压缩和按秩合并来提高效率。

findRedundantConnection 方法:遍历每条边,使用并查集检测第一个形成环的边。

class UnionFind:
    def __init__(self, size):
        self.parent = list(range(size))  # 父节点
        self.rank = [1] * size  # 秩

    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])  # 路径压缩
        return self.parent[x]

    def union(self, x, y):
        rootX = self.find(x)
        rootY = self.find(y)
        if rootX != rootY:
            if self.rank[rootX] > self.rank[rootY]:
                self.parent[rootY] = rootX
            elif self.rank[rootX] < self.rank[rootY]:
                self.parent[rootX] = rootY
            else:
                self.parent[rootY] = rootX
                self.rank[rootX] += 1
            return True
        return False

class Solution:
    def findRedundantConnection(self, edges: list[list[int]]) -> list[int]:
        n = len(edges)
        uf = UnionFind(n + 1)  # 初始化并查集,节点编号从1到n
        for edge in edges:
            if not uf.union(edge[0], edge[1]):
                return edge

复杂度分析

  • 时间复杂度:\(O(E \cdot \alpha(E))\),其中 \(E\) 是边的数量,\(\alpha\)Ackermann 函数的反函数,可以看作是一个很小的常数。在并查集的操作中,findunion 的时间复杂度均为 \(O(\alpha(E))\)

  • 空间复杂度:\(O(E)\)。因为创建的父节点数组和秩数组的长度都为 \(E\)

completely

有点 6

评论