1. 题目
2. 题解
- isConnected[i][j]=1:表示第 i 个城市和第 j 个城市直接相连,其中 isConnected 每一行表示一个城市与其他城市直接相连的情况
- 对于 isConnected 数组来说,共有 isConnected.length 个城市,遍历所有城市:
- 若当前城市没有访问过,即 !visited[i]:说明是一个新的省份,此时 count + 1并且利用 DFS 将那些和这个城市相连的其他城市都标记为已访问(这些城市都是同一省份的)。
(1)DFS
class Solution {
public int findCircleNum (int[][] isConnected) {
int len = isConnected.length;
boolean[] visit = new boolean[len];
Arrays.fill(visit, false);
int count = 0;
for (int i = 0; i < len; i++) { // 遍历所有的城市
if (!visit[i]) {
dfs(isConnected, visit, i); //将那些和这个城市相连的其他城市都标记为已访问(这些城市都是同一省份的)。
count++;
}
}
return count;
}
//利用 DFS 将那些和这个城市相连的其他城市都标记为已访问(这些城市都是同一省份的)。
public void dfs(int[][] isConnected, boolean[] visit, int i){
visit[i] = true;
for (int j = 0; j < isConnected.length; j++) {
// i 和 j相等的对角线不会进入循环
if (!visit[j] && isConnected[i][j] == 1)
dfs(isConnected, visit, j); //继续找和当前城市直接相连的城市的 其他相连城市
}
}
}
(2)BFS
对于 BFS 来说,depth 每增加一次,队列中的所有节点都向前迈一步,这保证了一旦找到了一个终点,走的步数时最少的,它借助 “队列” 做到一步一步 “齐头并进”,是可以在没遍历完整棵树的时候就找到最短距离的。
class Solution {
public int findCircleNum (int[][] isConnected) {
int len = isConnected.length;
boolean[] visit = new boolean[len];
Arrays.fill(visit, false);
int count = 0;
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < len; i++) { //找出每行的起点,如该起点已连接其他省份 则跳过
if (visit[i])
continue;
count++;
queue.offer(i); //将起点加入队列
visit[i] = true;
while(!queue.isEmpty()){ //这个while为了找出:每个城市直接相连 / 间接相连的城市, 并置于true
int size = queue.size();
for (int j = 0; j < size; j++) { //继续找到每个城市连接的其他城市,将同一省份标为true
int m = queue.poll();
for (int n = 0; n < len; n++) {
if(isConnected[m][n] == 1 && !visit[n]){
visit[n] = true;
queue.offer(n); //找到每个城市直接相连接的城市,并通过队列置true
}
}
}
}
}
return count;
}
}