1319. 连通网络的操作次数(Number of Operations to Make Network Connected)

频次 ★★★ · 难度 🟡 · 高频:快手

题目

n 台电脑,用 connections 连接,可移动缆线到未连接的电脑。求连通所有电脑的最少移动次数,无法连通返回 -1。

思路

并查集:连通 n 个节点至少需要 n-1 条边;如果 connections 数量 < n-1 直接返回 -1。

用并查集统计多余的边(已经连通的组件间再连边 = 多余),以及连通分量数量。需要移动的次数 = 连通分量数 - 1(只要有足够的多余边)。

代码

public int makeConnected(int n, int[][] connections) {
    if (connections.length < n - 1) return -1;     // 边不够
 
    int[] parent = new int[n];
    for (int i = 0; i < n; i++) parent[i] = i;
    int components = n;                             // 初始 n 个孤立节点
 
    for (int[] c : connections) {
        int ra = find(parent, c[0]), rb = find(parent, c[1]);
        if (ra != rb) {
            parent[ra] = rb;
            components--;                           // 合并一个连通分量
        }
    }
    return components - 1;                          // 连通的边数
}
 
private int find(int[] parent, int x) {
    if (parent[x] != x) parent[x] = find(parent, parent[x]);
    return parent[x];
}

复杂度

  • 时间:O(n α(n))
  • 空间:O(n)

边界条件

  • 边数 < n-1:返回 -1

变式

易错点

  • 先判边数不足,再判需要移动次数(有多余边才能移动)
  • components 初始为 n,union 成功时减一

面试追问

  • 为什么最少移动次数 = components - 1? 每个连通分量看做一个节点,需要 components - 1 条边才能连成树

关联题