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

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

Example 1: ip

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

Example 2: it

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

Note:class

  1. N is in range [1,200].
  2. Mi = 1 for all students.
  3. If Mi = 1, then Mj = 1.

思路一:深度優先遍歷

每當遇到一個尚未加入任何朋友圈的人(即Mi=1),就開始遍歷其還未加入任何朋友圈的朋友,並再訪問這些朋友的朋友,將其加入改人所在的朋友圈(使Mj=0, Mi=0),直到M中全部的值都爲0,說明找到了全部的朋友圈。遍歷

public int findCircleNum(int[][] M) {  
    int numOfFriends = M.length;  
    int count = 0;  
    for (int i = 0 ; i<numOfFriends ; i++) {  
        if (M[i][i] == 1) {  
            count++;  
            traverseFriendCircle(M, i, i);  
        }  
    }  
    return count;  
}  
  
public void traverseFriendCircle(int[][] M, int friendIndex, int fromFriendIndex) {  
    M[fromFriendIndex][friendIndex] = 0;  
    M[friendIndex][fromFriendIndex] = 0;  
    M[friendIndex][friendIndex] = 0;  
    for (int i = 0 ; i<M.length ; i++) {  
        if (M[friendIndex][i] == 1) {  
            traverseFriendCircle(M, i, friendIndex);  
        }  
    }  
}

思路二:Union Find

這題就是標準的Union Find的題目,經過找到全部有關聯的節點,將其加入到一個關聯樹中,利用標準的Union Find的union和find操做便可找到全部的關聯樹。nio

private int[] parentRoot;  
private int[] ranks;  
  
private int findParent(int i) {  
    while (i != parentRoot[i]) {  
        parentRoot[i] = parentRoot[parentRoot[i]];  
        i = parentRoot[i];  
    }  
    return i;  
}  
  
private void union(int i, int j) {  
    int parentOfI = findParent(i);  
    int parentOfJ = findParent(j);  
    if (parentOfI == parentOfJ) {return;}  
    if (ranks[parentOfI] > ranks[parentOfJ]) {  
        parentRoot[parentOfJ] = parentOfI;  
        ranks[parentOfI]++;  
    } else {  
        parentRoot[parentOfI] = parentOfJ;  
        ranks[parentOfJ]++;  
    }  
}  
  
public int findCircleNum2(int[][] M) {  
    int numOfFriends = M.length;  
    parentRoot = new int[numOfFriends];  
    ranks = new int[numOfFriends];  
    for (int i = 0 ; i < numOfFriends ; i++) {  
        parentRoot[i] = i;  
    }  
    for (int i = 0 ; i<numOfFriends ; i++) {  
        for (int j = i+1 ; j<numOfFriends ; j++){  
            if (M[i][j] == 1) {  
                union(i, j);  
            }  
        }  
    }  
    int count = 0;  
    for (int i = 0 ; i<numOfFriends ; i++) {  
        if (parentRoot[i] == i) {  
            count++;  
        }  
    }  
    return count;  
}
相關文章
相關標籤/搜索