LeetCode 1319. 连通网络的操作次数(BFS/DFS/并查集)

   日期:2020-05-14     浏览:107    评论:0    
核心提示:文章目录1. 题目2. 解题2.1 BFS2.2 DFS2.3 并查集1. 题目用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 a 和 b。网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所网络

文章目录

    • 1. 题目
    • 2. 解题
      • 2.1 BFS
      • 2.2 DFS
      • 2.3 并查集

1. 题目

用以太网线缆将 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]
没有重复的连接。
两台计算机不会通过多条线缆连接。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

  • 首先至少需要有n-1条连接,才可能满足题意
  • 其次,求有多少个集团,集团的个数-1就是需要改的线缆数量
  • 可以用BFS、DFS、并查集来求有多少个集团

2.1 BFS

class Solution {
	unordered_map<int,unordered_set<int>> m;
public:
    int makeConnected(int n, vector<vector<int>>& connections) {
    	if(connections.size() < n-1)
    		return -1;
    	vector<int> visited(n,false);
    	for(auto& c : connections)
    	{
    		m[c[0]].insert(c[1]);
    		m[c[1]].insert(c[0]);
    	}
    	int count = 0, tp;
        queue<int> q;
    	for(int i = 0; i < n; ++i)
    	{
    		if(!visited[i])
    		{
    			count++;
    			visited[i] = true;
    			q.push(i);
    			while(!q.empty())
    			{
    				tp = q.front();
    				q.pop();
    				for(auto c : m[tp])
    				{
    					if(!visited[c])
    					{
    						q.push(c);
    						visited[c] = true;
    					}
    				}
    			}
    		}
    	}
    	return count-1;
    }
};

432 ms 58.9 MB

2.2 DFS

class Solution {
	unordered_map<int,unordered_set<int>> m;
public:
    int makeConnected(int n, vector<vector<int>>& connections) {
    	if(connections.size() < n-1)
    		return -1;
    	vector<int> visited(n,false);
    	for(auto& c : connections)
    	{
    		m[c[0]].insert(c[1]);
    		m[c[1]].insert(c[0]);
    	}
    	int count = 0;
    	for(int i = 0; i < n; ++i)
    	{
    		if(!visited[i])
    		{
    			count++;
    			visited[i] = true;
    			dfs(i,visited);
    		}
    	}
    	return count-1;
    }
    void dfs(int i, vector<int>& visited)
    {
        for(auto c : m[i])
        {
            if(!visited[c])
            {
                visited[c] = true;
                dfs(c, visited);
            }
        }
    }
};

392 ms 59.4 MB

2.3 并查集

并查集参考:数据结构–并查集(Disjoint-Set)

class dsu
{
public:
    vector<int> f;
    dsu(int n)
    {
        f.resize(n);
        for(int i = 0; i < n; ++i)
            f[i] = i;
    }
    int find(int x)
    {
        if(x == f[x])
            return x;
        return f[x] = find(f[x]);
    }
    void merge(int x, int y)
    {
        int fx = find(x);
        int fy = find(y);
        f[fx] = fy;
    }
    int countuni()
    {
        int count = 0;
        for(int i = 0; i < f.size(); ++i)
        {
            if(i == find(i))
                count++;
        }
        return count;
    }
};

class Solution {
public:
    int makeConnected(int n, vector<vector<int>>& connections) {
    	if(connections.size() < n-1)
    		return -1;
    	dsu uni(n);
        for(auto& c : connections)
            uni.merge(c[0],c[1]);
        return uni.countuni()-1;
    }
};

176 ms 29 MB

可以看出并查集占用内存较少,运行时间较快。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服