本文参考了大神文章https://blog.csdn.net/iteye_9214/article/details/82099516
应该这就是原创了,网上有很多人模仿着写。
leetcode上的这道题,是并查集最简单直观的使用。简单来说,在基于已经构建好的关系网,要直接判断A和B是否是好朋友很难,但是如果可以知道A和C是好朋友,B和C也是好朋友,那么A和B自然也是好朋友了。但是人多了怎么办呢。可以在每个朋友圈找出一个孩子王,那么只要知道两个人的孩子王是否一样就可以判断他们是否是好朋友。基于这个思路可以得出并查集的一般解题方法
并查集的题一般分两步走:
1.分析题目,得出顶点数
这里的顶点可能理解起来比较抽象,比如像这道题,N名学生就是N个顶点。
2.构建顶点上级数组
并不是所有孩子都和孩子王玩得好(直接认识),所以构建一个pre[N]数组。pre[i] 表示学生 i 的上级学生。一直顺着上级学生找就可以找到孩子王,i 是孩子王的条件就是pre[i] = i,即他的上级就是他自己。
那么,说到底,怎么构建pre数组呢。首先将pre数组初始化,令 pre[i] = i 。然后根据题目中给的顶点(学生)之间的关系构建。比如A认识B,就可以令pre[A] = B。其实 pre[B] =A 也可以,这只会影响朋友圈内部的结构,不会影响两个学生是否是朋友。
代码如下
public int findCircleNum(int[][] M) {
int len = M.length;
pre = new int[len];
for (int i = 0; i < len; i++){
pre[i] = i;
}
int total = len; // 最开始每个同学都说个独立的个体,所以同学的个数就是朋友圈的个数。
for (int i = 0; i < len; i++){
for (int j = i + 1; j < len; j++){
if (M[i][j] == 1){
// 此时已知i