题目
有 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 <= 200n == isConnected.lengthn == isConnected[i].lengthisConnected[i][j]为1或0isConnected[i][i] == 1isConnected[i][j] == isConnected[j][i]
题解
分析:这个问题是一个典型的图论问题,可以通过并查集数据结构来解决。问题的目的是找出图中的连通分量数量,每个连通分量代表一个省份。
并查集:是一种数据结构,用于处理一些涉及集合元素的合并及查询问题,特别适用于解决一些不交集的合并和查找问题。以下是并查集的应用场景:
- 网络连通:在网络中判断两个节点是否连通。
- 任务调度:可以用于管理任务分组和分配。
- 动态连通:在动态变化的环境中,需要频繁地合并和查询集合的连通性。
代码:
class Solution {
public int[] set;
// init(int n):初始化并查集
public void init(int n) {
set = new int[n];
for (int i = 0; i < n; i++) {
set[i] = i;
}
}
// find(int x):确定 x 属于哪个子集
public int find(int x) {
return x == set[x] ? x : (set[x] = find(set[x]));
}
// union(int x, int y):合并 x 和 y 为一个子集
public void union(int x, int y) {
set[find(x)] = find(y);
}
public int findCircleNum(int[][] isConnected) {
int len = isConnected.length, count = 0;
// 1. 初始化并查集
init(len);
// 2. 将连接的省份进行合并,由于是无向图,所以考虑一半即可
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (isConnected[i][j] == 1) {
union(i, j);
}
}
}
// 3. 计算省份数量
for (int i = 0; i < len; i++) {
if (set[i] == i) count++;
}
return count;
}
}