并查集基础模板,简单易上手!

315 阅读1分钟

这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

题目

有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。

返回矩阵中 省份 的数量。

示例

image.png

输入: isConnected = [[1,1,0],[1,1,0],[0,0,1]]
输出: 2

image.png

输入: isConnected = [[1,0,0],[0,1,0],[0,0,1]]
输出: 3

提示

  • 1 <= n <= 200
  • m = isConnected.length
  • n == isConnected[i].length
  • isConnected[i][j]10
  • isConnected[i][i] == 1
  • isConnected[i][j] == isConnected[j][i]

解题思路

并查集

并查集模板

class UnionFind{
    // 元素数组,用来保存关联关系
    private int[] elements;

    // 初始化
    public UnionFind(int n){
        this.elements = new int[n];
        for(int i = 0; i < n; ++i){
            this.elements[i] = i;
        }
    }

    // 合并元素,将其关联成统一集合
    public void union(int a, int b){
        elements[find(a)] = find(b);
    }

    // 查找元素所属的集合编号
    public int find(int element){
        if(elements[element] != element){
            elements[element] = find(elements[element]);
        }
        return elements[element];
    }
    
    // 判断两个元素是否为同一集合元素
    public boolean isConnected(int a, int b){
        return find(a) == find(b);
    }
}

代码实现

class Solution {
    public int findCircleNum(int[][] isConnected) {
        int n = isConnected.length;
        // 创建并查集对象
        UnionFind uf = new UnionFind(n);

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                // 将省份中城市关联为同一集合
                if (isConnected[i][j] == 1) {
                    uf.union(i, j);
                }
            }
        }

        // 查找集合的数量
        int circles = 0;
        for (int i = 0; i < n; i++) {
            if (uf.elements[i] == i) {
                circles++;
            }
        }
        // 返回结果
        return circles;
    }

    // 并查集
    class UnionFind{
        private int[] elements;
        
        public UnionFind(int n){
            this.elements = new int[n];
        }

        public void union(int a, int b){
            elements[find(a)] = find(b);
        }

        public int find(int element){
            if(elements[element] != element){
                elements[element] = find(elements[element]);
            }
            return elements[element];
        }

        public boolean isConnected(int a, int b){
            return find(a) == find(b);
        }
    }
}

 复杂度分析

  •   时间复杂度:O(N2logN)O(N^2logN)
  •   空间复杂度:O(N)O(N)

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处: leetcode-cn.com/problems/nu…