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);
            }
        }
    }

 

posted on 2018-09-07 11:05  葫芦胡同749  阅读(121)  评论(0编辑  收藏  举报

导航