题解 | #城市群数量#
城市群数量
https://www.nowcoder.com/practice/71cde4dee669475f94d8d38832374ada
import java.util.*;
/**
* NC345 城市群数量
* @author d3y1
*/
public class Solution {
private int result = 0;
private int N;
private boolean[] isVisited;
private HashSet<Integer>[] adj;
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 程序入口
*
* @param m int整型ArrayList<ArrayList<>>
* @return int整型
*/
public int citys (ArrayList<ArrayList<Integer>> m) {
// return solution1(m);
// return solution2(m);
return solution3(m);
}
/**
* dfs
* @param m
* @return
*/
private int solution1(ArrayList<ArrayList<Integer>> m){
N = m.size();
isVisited = new boolean[N];
adj = new HashSet[N];
for(int i = 0; i < N; i++){
adj[i] = new HashSet<>();
}
for(int i = 0; i < N; i++){
for(int j = i+1; j < N; j++){
if(m.get(i).get(j) == 1){
adj[i].add(j);
adj[j].add(i);
}
}
}
for(int i = 0; i < N; i++){
if(!isVisited[i]){
dfs(i);
result++;
}
}
return result;
}
/**
* 递归
* @param city
*/
private void dfs(int city){
if(isVisited[city]){
return;
}
isVisited[city] = true;
for(int adjCity: adj[city]){
dfs(adjCity);
}
}
/**
* bfs
* @param m
* @return
*/
private int solution2(ArrayList<ArrayList<Integer>> m){
N = m.size();
isVisited = new boolean[N];
adj = new HashSet[N];
for(int i = 0; i < N; i++){
adj[i] = new HashSet<>();
}
for(int i = 0; i < N; i++){
for(int j = i+1; j < N; j++){
if(m.get(i).get(j) == 1){
adj[i].add(j);
adj[j].add(i);
}
}
}
for(int i = 0; i < N; i++){
if(!isVisited[i]){
bfs(i);
result++;
}
}
return result;
}
/**
* 非递归: 队列
* @param city
*/
private void bfs(int city){
Queue<Integer> queue = new LinkedList<>();
queue.offer(city);
int currCity;
while(!queue.isEmpty()){
currCity = queue.poll();
isVisited[currCity] = true;
for(int adjCity: adj[currCity]){
if(!isVisited[adjCity]){
queue.offer(adjCity);
}
}
}
}
/**
* 并查集
* @param m
* @return
*/
private int solution3(ArrayList<ArrayList<Integer>> m){
N = m.size();
if(N == 1){
return 1;
}
UnionFind uf = new UnionFind(N);
for(int i = 0; i < N; i++){
for(int j = i+1; j < N; j++){
if(m.get(i).get(j) == 1){
uf.union(i, j);
}
}
}
return uf.connect();
}
/**
* 并查集类
*/
private class UnionFind{
// 连通分量
int connect;
// 记录父节点
int[] parent;
// 构造函数 n为结点个数
UnionFind(int n){
// 初始连通分量
this.connect = n;
this.parent = new int[n];
for(int i=0; i<n; i++){
// 初始父节点指向自己
parent[i]=i;
}
}
// 找到x的根节点
int find(int x){
while(parent[x] != x){
x = parent[x];
}
return x;
}
// 连通p和q
void union(int p, int q){
int rootP = find(p);
int rootQ = find(q);
if(rootP != rootQ){
parent[rootP] = rootQ;
connect--;
}
}
// 返回连通分量
int connect(){
return connect;
}
}
}
查看14道真题和解析