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