其他分享
首页 > 其他分享> > leetcode547. 省份数量(dfs 并查集)

leetcode547. 省份数量(dfs 并查集)

作者:互联网

链接:https://leetcode-cn.com/problems/number-of-provinces/

题目

有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。

返回矩阵中 省份 的数量。

用例

示例 1:

输入:isConnected = [[1,1,0],[1,1,0],[0,0,1]]
输出:2
示例 2:

输入:isConnected = [[1,0,0],[0,1,0],[0,0,1]]
输出:3

提示:

1 <= n <= 200
n == isConnected.length
n == isConnected[i].length
isConnected[i][j] 为 1 或 0
isConnected[i][i] == 1
isConnected[i][j] == isConnected[j][i]

思路

方法1
设置访问数组,dfs遍历每个未访问过的节点,计数

class Solution {
public:
	int findCircleNum(vector<vector<int>>& isConnected) {
		int n = isConnected.size(), ans = 0;
		vector<int>vis(n);
		for (int i = 0; i<n; ++i){
			if(!vis[i]){
				dfs(isConnected, vis, n, i);
				ans++;
			}
		}
		return ans;
	}
	void dfs(vector<vector<int>>&isConnected, vector<int>&vis, int n, int s){
		if (vis[s])
			return;
		vis[s] = 1;
		for (int i = 0; i<n; ++i){
			if (!vis[i] && isConnected[s][i] == 1){
				dfs(isConnected, vis, n, i);
			}
		}
	}
};

方法2
并查集
本题时标准的并查集模板题 ,对于需要求连通分量相关的题都可以使用并查集做
并查集是一种数据结构
并查集这三个字,一个字代表一个意思。
并(Union),代表合并
查(Find),代表查找
集(Set),代表这是一个以字典为基础的数据结构,它的基本功能是合并集合中的元素,查找集合中的元素
并查集的典型应用是有关连通分量的问题
并查集解决单个问题(添加,合并,查找)的时间复杂度都是O(1)O(1)
因此,并查集可以应用到在线算法中
并查集模板

class UnionFind{
public:
  //查找祖先
    int find(int x){
        int root = x;
        while(father[root] != -1){//当前root不是-1,即自己不是根节点时,继续找根节点
            root = father[root];
        }
        
        while(x != root){
            int original_father = father[x];//取普通父节点
            father[x] = root;//对于道路上每个祖先节点都改为root值 状态压缩
            x = original_father;
        }
        
        return root;
    }
    
    bool is_connected(int x,int y){//判断是否联通
        return find(x) == find(y);
    }
    
    void merge(int x,int y){//合并连通分量
        int root_x = find(x);
        int root_y = find(y);
        
        if(root_x != root_y){
            father[root_x] = root_y;
        }
    }
    
    void add(int x){//增加新的值
        if(!father.count(x)){
            father[x] = -1;
        }
    }
    
private:
    // 记录父节点
    unordered_map<int,int> father;
};

标签:leetcode547,int,查集,father,isConnected,相连,dfs,root
来源: https://www.cnblogs.com/kitamu/p/15556209.html