There are students in the class N. Some of them are friends, some are not. Their friendship has is transitive. If you know a friend B of A, B C is a friend, so we can assume that A is C friend. The so-called circle of friends, is the set of all your friends.
Given an N * N matrix M, represents the friendship between classes high school students. If M [i] [j] = 1, represents a known i-th and j-th student mutual friendship, otherwise I do not know. You must be exported to all students in the total number of known circle of friends.
Example 1:
Enter: [[1,1,0], [1,1,0], [0,0,1]] Output: 2 Description: Known students and students 0 1 mutual friends, they are in a circle of friends. The first two students themselves in a circle of friends. 2 is returned.
Example 2:
Input: [[1,1,0], [1,1,1], [0,1,1]] Output: 1 Description: known Student Student 0 and 1 mutual friend, a student and the student 2 mutually friends, so students and students 0 2 is also a friend, so three of them in a circle of friends, returns 1.
note:
- N within the [1,200] range.
- For all students, M [i] [i] = 1.
- If M [i] [j] = 1, then there are M [j] [i] = 1.
Analysis: This question needs to apply clear meaning of the questions, as the matrix, the matrix representing each value of n * n position is not as a friend.
1, in fact, this question can follow that question the largest number of islands to do, seeking the maximum number of islands in search time is about up and down next to each value element, but the same problem can search the same horizontal and vertical All values of the row, then depth of search (or at wide search)
2, there is a solution that is disjoint-set
1, depth-first search
class Solution { int len; public int findCircleNum(int[][] m) { len = m.length; int ans = 0; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { if (m[i][j] == 1) { ans++; clear(m, i, j); } } } return ans; } public void clear(int[][] m, int q, int p) { if (m[q][p] == 0) { return; } m[q][p] = 0; for (int i = 0; i < len; i++) { clear(m, i, p); } for (int i = 0; i < len; i++) { clear(m, q, i); } } }
2, breadth-first search
public class Location{ int x; int y; Location(int m, int n){ x = m; y = n; } } class Solution { int len; Queue<Location> queue = new LinkedList<Location>(); public int findCircleNum(int[][] m) { len = m.length; int ans = 0; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { if (m[i][j] != 0) { ans++; queue.add(new Location(i, j)); while (queue.size() != 0) { Location l = queue.remove(); if (m[l.x][l.y] != 0) { m[l.x][l.y] = 0; for (int k = 0; k < len; k++) { queue.add(new Location(l.x, k)); queue.add(new Location(k, l.y)); } } } } } } return ans; } }
3, disjoint-set
class Solution { int[] arr; int[] count; int allgroup = 0; public int findCircleNum(int[][] m) { int len = m.length; if (len == 0) { return 0; } arr = new int[len]; count = new int[len]; allgroup = len; for (int i = 0; i < len; i++) { arr[i] = i; count[i] = 1; } for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { if (m[i][j] == 0) { continue; } int roota = find(i); int rootb = find(j); if (roota == rootb) { continue; } allgroup--; if (count[roota] > count[rootb]) { arr[rootb] = roota; count[roota] += count[rootb]; } else { arr[roota] = rootb; count[rootb] += count[roota]; } } } return allgroup; } public int find(int a) { while (arr[a] != a) a = arr[a]; return a; } }