0095 经典算法系列——并查集(Union-Find)

概念TODO

UF的标准模板

算法实战

  • 等式方程的可满足性(medium)
  • 朋友圈(medium)
  • 最长连续序列(hard)

下面将介绍以上题目的实现:
等式方程的可满足性(medium)
分析

  • List item
class Solution {
    public boolean equationsPossible(String[] equations) {
        int n = equations.length;
        UF uf = new UF();
        
        for (int i = 0; i < n; i++) {
            if (equations[i].charAt(1) == '='){
                uf.union(equations[i].charAt(0) - 'a', equations[i].charAt(3) - 'a');
            }
        }
        
        for (int i = 0; i < n; i++) {
            if (equations[i].charAt(1) == '=' && !uf.connected(equations[i].charAt(0) - 'a', equations[i].charAt(3) - 'a') ){
               return false;         
            }
            if (equations[i].charAt(1) == '!' && uf.connected(equations[i].charAt(0) - 'a', equations[i].charAt(3) - 'a') ){
               return false;         
            }
        }     
        return true;
 
    }
    
    class UF {
        int[] id;
        int[] size;
        public UF() {
            id = new int[26];
            size = new int[26];
            
            for (int i = 0; i < 26; i++){
                id[i] = i;
                size[i] = 1;
            }
        }
        public int find(int p){
            while (p != id[p]) {
                id[p] = id[id[p]];
                p = id[p];
            }
            return p;
        }
        public void union(int p, int q) {
            int pRoot = find(p);
            int qRoot = find(q);
            if (pRoot == qRoot) return;
            if (size[pRoot] < size[qRoot]){
                id[pRoot] = qRoot;
                size[qRoot] += size[pRoot];
            }else {
                id[qRoot] = pRoot;
                size[pRoot] += size[qRoot];
            }
        }
        
        public boolean connected(int p, int q) {
            return find(p) == find(q);
        }
    }
}

执行用时 :1 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗 :39.3 MB, 在所有 Java 提交中击败了16.67%的用户

  • 547 朋友圈(medium)

班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。

给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j
个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。

示例 1:

输入: [[1,1,0], [1,1,0], [0,0,1]] 输出: 2 说明:已知学生0和学生1互为朋友,他们在一个朋友圈。
第2个学生自己在一个朋友圈。所以返回2

class Solution {
    //Union Find
    public int findCircleNum(int[][] M) {
        int n = M.length;
        UF uf = new UF(n);
        
        for (int i = 0; i < n; i++) 
            for (int j = 0; j < n; j++) {
                if (M[i][j] == 1)
                    uf.union(i, j);
            }
        
        return uf.count;
        
    }
    class UF {
        int[] id;
        int[] size;
        public int count;
        public UF(int n) {
            id = new int[n];
            size = new int[n];
            count = n;
            for (int i = 0; i < n; i++) {
                id[i] = i;
                size[i] = 1;
            }
        }
        public int find(int p) {
            while (p != id[p]) {
                id[p] = id[id[p]];
                p = id[p];
            }
            return p;
        }
        
        public void union(int p, int q) {
            int pRoot = find(p);
            int qRoot = find(q);
            if (pRoot == qRoot) return;
            if (size[pRoot] < size[qRoot]) {
                id[pRoot] = qRoot;
                size[qRoot] += size[pRoot];
                count--;
            } else {
                id[qRoot] = pRoot;
                size[pRoot] += size[qRoot];
                count--;
            }
        }
    }

DFS解法

public int findCircleNum(int[][] M) {
        int m  = M.length;
        int count = 0;
        int[] visited = new int[m];  //all 0
        
        for (int i = 0; i < m; i++)
            if (visited[i] == 0){
                dfs(M, i, visited);
                count++;
            }

        return count;
    }
    
    public void dfs(int[][] M, int i, int[] visited) {
        for (int j = 0; j < M.length; j++){
            if (visited[j] == 0 && M[i][j] == 1){
                visited[j] = 1;
                dfs(M, j, visited);
            }
        }
          
    }

你可能感兴趣的:(Algorithm)