并查集的应用

在图论的算法题中,虽然最常用的算法是DFS和BFS,但是在求连通分量数量的时候,借助并查集这一数据结构是是十分简单的,以leetcode-547,省份数量 这道题举例。

public int findCircleNum(int[][] isConnected) {
        int size = isConnected.length;
        UnionFind unionFind = new UnionFind(size);
        for (int i = 0; i < size; i++) {
            for (int j = i + 1; j < size; j++) {
                if (isConnected[i][j] == 1) {
                	// 如果两省份相连,直接使用并查集联合
                    unionFind.unionElement(i, j);
                }
            }
        }
        int res = 0;
        for (int i = 0; i < size; i++) {
            if (unionFind.find(i) == i) {
                res++;
            }
        }
        return res;
    }
    /**
     * 并查集的数据结构
     */
    class UnionFind {
        int[] parent;
        int[] rank;

        public UnionFind(int size) {
            this.parent = new int[size];
            this.rank = new int[size];

            for (int i = 0; i < size; i++) {
                parent[i] = i;
                rank[i] = 1;
            }
        }


        public boolean isConnected(int p, int q) {
            return find(p) == find(q);
        }

        private int find(int p) {
            while (p != parent[p]) {
                parent[p] = parent[parent[p]];
                p = parent[p];
            }
            return p;
        }

        public void unionElement(int p, int q) {
            int proot = find(p);
            int qroot = find(q);

            if (rank[proot] < rank[qroot]) {
                parent[proot] = qroot;
            } else if (rank[proot] > rank[qroot]) {
                parent[qroot] = proot;
            } else {
                parent[proot] = qroot;
                rank[qroot] += 1;
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值