[路飞][LeetCode]1319_连通网络的操作次数

137 阅读1分钟

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战

看一百遍美女,美女也不一定是你的。但你刷一百遍算法,知识就是你的了~~

谁能九层台,不用累土起!

题目地址

题目

用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 a 和 b

网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。

给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。

示例 1:

输入: n = 4, connections = [[0,1],[0,2],[1,2]]
输出: 1
解释: 拔下计算机 12 之间的线缆,并将它插到计算机 13 上。

示例 2:

输入: n = 6, connections = [[0,1],[0,2],[0,3],[1,2],[1,3]]
输出: 2

示例 3:

输入: n = 6, connections = [[0,1],[0,2],[0,3],[1,2]]
输出: -1
解释: 线缆数量不足。

示例 4:

输入: n = 5, connections = [[0,1],[0,2],[3,4],[2,3]]
输出: 0

提示:

  • 1 <= n <= 10^5
  • 1 <= connections.length <= min(n*(n-1)/2, 10^5)
  • connections[i].length == 2
  • 0 <= connections[i][0], connections[i][1] < n
  • connections[i][0] != connections[i][1]
  • 没有重复的连接。
  • 两台计算机不会通过多条线缆连接。

解题思路

  • 这题我们依旧使用并查集来做,相信看过我之前文章的小伙伴们已经很熟悉了,这里就不做过多阐述

  • 根据题目,我们很简单可以得出以下结论

    • 要将n个电脑连接起来,我们最少需要n-1个网线,也就是说我们判断connections.length也就是网线的数量小于需要的最少数量n-1,也就是肯定连不起来,直接返回-1

    • 初始化时每个电脑都是孤立的,共有n个点集合,故初始化时arr长度为n

    • 根据connections将两电脑连线,生成点集,此时未连接电脑数量会减少。当点集增大到包含3个及以上时,从connections取出一条新的网线信息,则需要判断,该线的两台电脑是否已连接,如果已连接,就将未连接电脑数量--,反之不做任何处理

    • 我们遍历connections,当connections信息用完,此时的n也就说明剩下的孤立的电脑的台数

    • 需要的网线数量为电脑台数-1

解题代码

var makeConnected = function(n, connections) {
    if (connections.length < n - 1) return -1;
    const union = new Union(n)
    for(let [a,b] of connections){
        if(union.merge(a,b)) n--
    }
    return n-1
};

class Union {
    constructor(n){
        this.arr = new Array(n).fill(0).map((v,i)=>i)
    }

    find(i){
        if(this.arr[i]==i) return i
        return this.find(this.arr[i])
    }

    connect(a,b){
        return this.find(a) == this.find(b)
    }

    merge(a,b){
        if(this.connect(a,b)) return false
        this.arr[this.find(a)] = this.find(b)
        return true
    }
}

如有任何问题或建议,欢迎留言讨论!