怎么又是图 老子不会啊
题目
https://leetcode-cn.com/problems/number-of-provinces/
方法一:深度优先搜索
分析
深度优先搜索的思路是很直观的。遍历所有城市,对于每个城市,如果该城市尚未被访问过,则从该城市开始深度优先搜索,通过矩阵 \textit{isConnected}isConnected 得到与该城市直接相连的城市有哪些,这些城市和该城市属于同一个连通分量,然后对这些城市继续深度优先搜索,直到同一个连通分量的所有城市都被访问到,即可得到一个省份。遍历完全部城市以后,即可得到连通分量的总数,即省份的总数。
代码
class Solution {
int[][] isConnected;
boolean[] visited;
int n=0;
int count=0;
public int findCircleNum(int[][] isConnected) {
n=isConnected.length;
visited=new boolean[n];
this.isConnected=isConnected;
for(int i=0;i<n;i++){
if(visited[i]==false){
visited[i]=true;
dfs(i);
count++;
}
}
return count;
}
public void dfs(int x){
for(int i=0;i<n;i++){
if(visited[i]==false&&isConnected[i][x]==1){
visited[i]=true;
dfs(i);
}
}
}
}
复杂度
时间复杂度:O(n^2),其中 n 是城市的数量。需要遍历矩阵 n 中的每个元素。
空间复杂度:O(n),其中 n 是城市的数量。需要使用数组visited 记录每个城市是否被访问过,数组长度是 n,递归调用栈的深度不会超过 n。
结果
方法二:广度优先搜索
分析
也可以通过广度优先搜索的方法得到省份的总数。对于每个城市,如果该城市尚未被访问过,则从该城市开始广度优先搜索,直到同一个连通分量中的所有城市都被访问到,即可得到一个省份。
代码
class Solution {
public int findCircleNum(int[][] isConnected) {
int n=isConnected.length;
boolean[] visited=new boolean[n];
LinkedList<Integer> list=new LinkedList<>();
int count=0;
for(int i=0;i<n;i++){
if(visited[i]==false){
list.addLast(i);
while(!list.isEmpty()){
int a=list.removeFirst();
visited[a]=true;
for(int j=0;j<n;j++){
if(isConnected[a][j]==1&&visited[j]==false){
list.addLast(j);
}
}
}
count++;
}
}
return count;
}
}
复杂度
时间复杂度:O(n^2),其中 n 是城市的数量。需要遍历矩阵 isConnected 中的每个元素。
空间复杂度:O(n),其中 n 是城市的数量。需要使用数组visited 记录每个城市是否被访问过,数组长度是 n,广度优先搜索使用的队列的元素个数不会超过 n。