547. Friend Circles 求间接朋友形成的朋友圈数量

[抄题]:

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example 1:

Input: 
[[1,1,0],
 [1,1,0],
 [0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. 
The 2nd student himself is in a friend circle. So return 2.

 

Example 2:

Input: 
[[1,1,0],
 [1,1,1],
 [0,1,1]]
Output: 1
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, 
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

 [暴力解法]:

时间分析:

空间分析:

 [优化后]:

时间分析:

空间分析:

[奇葩输出条件]:

[奇葩corner case]:

[思维问题]:

忘记uf怎么写了:写个find,然后初始化岛屿数量为n,再调用find来减少。

[英文数据结构或算法,为什么不用别的数据结构或算法]:

[一句话思路]:

[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

[画图]:

[一刷]:

root1和root0不相等的时候,直接把root0的全部都迁移到root1下面,而不是只迁移root[j]的

if (root0 != root1) {
                        roots[root1] = root0;
                        count--;
                    }

[二刷]:

[三刷]:

[四刷]:

[五刷]:

  [五分钟肉眼debug的结果]:

[总结]:

[复杂度]:Time complexity: O(n) Space complexity: O(n)

[算法思想:迭代/递归/分治/贪心]:

[关键模板化代码]:

find里面是while循环,毕竟要一直find,保存所有路径

[其他解法]:

[Follow Up]:

[LC给出的题目变变变]:

 [代码风格] :

 [是否头一次写此类driver funcion的代码] :

 [潜台词] :

class Solution {
    public int findCircleNum(int[][] M) {
        //corner case
        if (M == null || M.length == 0) return 0;
        
        //initialization: count = n, each id = id
        int m = M.length;
        int count = m;
        int[] roots = new int[m];
        for (int i = 0; i < m; i++) roots[i] = i; 
        
        //for loop and union find
        for (int i = 0; i < m; i++) {
            for (int j = i + 1; j < m; j++) {
                //if there is an edge, do union find
                if (M[i][j] == 1) {
                    int root0 = find (roots, i);
                    int root1 = find (roots, j);
                    
                    if (root0 != root1) {
                        roots[root1] = root0;
                        count--;
                    }
                }
            }
        }
        
        //return count
        return count;
    }
    
    public int find (int[] roots, int id) {
        while (id != roots[id]) {
            id = roots[roots[id]];
        }
        return id;
    }
}
View Code
原文地址:https://www.cnblogs.com/immiao0319/p/9414768.html