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.ide

Example 1:oop

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.

 [暴力解法]:spa

時間分析:debug

空間分析:code

 [優化後]:blog

時間分析:遞歸

空間分析:

[奇葩輸出條件]:

[奇葩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
相關文章
相關標籤/搜索