Union Find

连通

就动态连通性这个场景而言,我们需要解决的问题可能是:
给出两个节点,判断它们是否连通,如果连通,不需要给出具体的路径
给出两个节点,判断它们是否连通,如果连通,需要给出具体的路径

就上面两种问题而言,虽然只有是否能够给出具体路径的区别,但是这个区别导致了选择算法的不同,第一种情况,即不需要给出具体路径的Union-Find算法,而第二种情况可以使用基于DFS的算法。

Union Find_第1张图片
1339479136_7058.png

reference: http://blog.csdn.net/dm_vincent/article/details/7655764

Graph Representation & Build:http://www.jianshu.com/p/857e7cc63077

technique:
(1) linked structure a -> b -> c -> d(root)
(2) weighted quick union: auto-balanced using this.sz() during union()
(3) path compression: id[i] = id[id[i]] during find()

写法:
UF构造的时候,UF()函数要根据具体修改,N的数量,init方式,是否需要传入grid等等。
union的时候,weighted quick union:将size大的id作为parent,"自动平衡",(但一定还是都联通的)
Time Complexity: find: O(TreeHeight), union: O(TreeHeight)
Space Complexity: O(N)

class UF {
        private int[] id;  
        private int[] sz;  // for an id, the number of elements in that id
        private int count; // number of sort of id

        public UF(int m, int n) {
            
            int N = m * n + 1;
            this.id = new int[N];
            this.sz = new int[N];
            this.count = 0;
            
            // init
            for (int i = 0; i < N; i++) {
                this.id[i] = i;
                this.sz[i] = 1;
                this.count++;
            }
        }

        public void union(int p, int q) {
            int p_root = find(p), q_root = find(q);
            // weighted quick union
            ///*
            if(p_root == q_root) return;
            if (sz[p_root] < sz[q_root]) { 
                id[p_root] = q_root; sz[q_root] += sz[p_root];
            } else {
                id[q_root] = p_root; sz[p_root] += sz[q_root];
            }
            --count;
            //*/
            
            // regular
            /*
            if(p_root == q_root) return;
            id[p_root] = q_root;
            --count;
            */
        }

        public int find(int i) { // path compression
          /* while(i != id[i]) i = id[i]; */ regular, untested
            for (;i != id[i]; i = id[i])
                id[i] = id[id[i]]; 
            return i;
        }

        public boolean connected(int p, int q) {
            int p_root = find(p);
            int q_root = find(q);
            if(p_root != q_root) return false;
            else return true;
        }

        public int count() { 
            return this.count; 
        }
        
    }

Example:

130 Surrounded Regions: http://www.jianshu.com/p/0ff5fb9466a9
200 Number of Islands: http://www.jianshu.com/p/f834dbd46dd3
261 Graph Valid Tree www.jianshu.com/p/ffd3a82e0388
323 Number of Connected Components in an Undirected Graph http://www.jianshu.com/p/bb815473eb87

你可能感兴趣的:(Union Find)