美文网首页
[并查集]并查集应用之省份数量

[并查集]并查集应用之省份数量

作者: 铜炉 | 来源:发表于2021-02-15 21:55 被阅读0次

    前言

    经过并查集的升级路线一二三四之后,我们现在得到了一个相对来说比较完美的并查集数据结构,从本篇开始应用这个并查集为我们解决实际的算法问题。

    省份数量

    力扣547题
    有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。
    省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。
    给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。
    返回矩阵中 省份 的数量。

    题目分析

    题目中需要计算的省份数量,实际上就是并查集的森林中树的数量,好在我们在并查集结构中已经使用count来标记了并查集中不同树的数量,所以,我们将链接的城市合并后,最终返回并查集中的count值即可。

    题目步骤分解

    1、构建并查集;
    2、n*n矩阵,n代表着分量的数量,初始化并查集的时候,分量个数传入n;
    3、遍历二维矩阵,如果对应值是1,就合并两个分量;
    4、遍历结束后,返回并查集的count;

    书写代码

    并查集的准备

    class QuickUnionUnionFind {
    
        // 存储连分量
        protected int[] id;
        // 当前并查集不同的连通分量总数
        protected int count;
        
        public QuickUnionUnionFind(int n) {
            // 初始化时,没个分量互不连通
            this.count = n;
            // 初始化一个容纳全量分量的数组
            this.id = new int[n];
            for (int i = 0; i < n; i++) {
                // 没个分量初始值指向自身
                id[i] = i;
            }
        }
    
        void union(int p, int q) {
            // 找到p的标识
            int pId = find(p);
            // 找到q的标识
            int qId = find(q);
    
            // 如果两个标识相等,代表已经合并
            if (pId == qId) return;
    
            // 如果不相等,直接让分量q的标识指向p
            id[pId] = qId;
            // 每次合并操作,会降低一个不同分量组
            count--;
        }
    
        int find(int p) {
            // 沿着标识路径一路寻找,直到找到树的标识
            while (p != id[p]) p = id[p];
            return p;
        }
    }
    
    

    算法代码

    class Solution {
        public int findCircleNum(int[][] isConnected) {
            // n为分量总数
            int n = isConnected.length;
            QuickUnionUnionFind quuf = new QuickUnionUnionFind(n);
    
            for (int i = 0; i < isConnected.length; i++) {
                int[] row = isConnected[i];
                for (int k = i; k < row.length; k++) {
                    
                    if (isConnected[i][k] == 1) {
                        // 如果矩阵值为1,代表连通,需要合并
                        quuf.union(i, k);
                    }
                }
            }
    
            // 返回树的个数
            return quuf.count;
    
        }
    }
    

    相关文章

      网友评论

          本文标题:[并查集]并查集应用之省份数量

          本文链接:https://www.haomeiwen.com/subject/welmxltx.html