Friend Circles(547)
1. Union Find
时间O(N^2)
空间O(N^2)
简单版
public int findCircleNum(int[][] M) { if( M == null || M.length == 0) return 0; int n = M.length; int[] f = new int[n]; for(int i = 0 ; i < n; ++i) f[i] = i; for(int i = 0 ; i < n; ++i){ for(int j = i + 1; j < n; ++j){ if(M[i][j] == 1){ int pi = parent(i, f); int pj = parent(j, f); if(pi != pj){ f[pi] = pj; } } } } Set<Integer> set = new HashSet<>(); for(int i: f) set.add(parent(i,f)); return set.size(); } private int parent(int n, int[] f){ if(f[n] != n){ f[n] = parent(f[n], f); } return f[n]; }
复杂版
class UnionFind{ int[] root; int count; public UnionFind(int n){ root = new int[n]; for(int i = 0 ; i < n; ++i){ root[i] = i; count = n; } } public void union(int n, int m){ int root_n = find(n); int root_m = find(m); if(root_n != root_m){ root[root_n] = root[root_m]; count--; } } public int find(int n){ if(root[n] != n){ root[n] = find(root[n]); } return root[n]; } } class Solution { public int findCircleNum(int[][] M) { if( M== null || M.length == 0) return 0; int n = M.length; int m = M[0].length; UnionFind uf = new UnionFind(n); for(int i = 0 ; i < n; ++i){ for(int j = i+1 ; j < m; ++j){ if(M[i][j] == 1){ uf.union(i, j); } } } return uf.count; } }
2. DFS ** 比UF快的多
时间O(N^2)
空间O(N^2)
public int findCircleNum(int[][] M) { if( M == null || M.length == 0) return 0; int result = 0; boolean[] visited = new boolean[M.length]; for(int i = 0 ; i < M.length; ++i){ if(!visited[i]){ dfs(i, visited, M); result++; } } return result; } private void dfs(int n, boolean[] visited,int[][] M){ for(int j = 0; j < M[0].length; ++j){ if(!visited[j] && M[n][j] == 1){ visited[j] = true; dfs(j, visited, M); } } }