LeetCode-统计完全连通分量的数量

题目要求:

给你一个整数 n 。现有一个包含 n 个顶点的 无向 图,顶点按从 0 到 n - 1 编号。给你一个二维整数数组 edges 其中 edges[i] = [ai, bi] 表示顶点 ai 和 bi 之间存在一条 无向 边。

返回图中 完全连通分量 的数量。

如果在子图中任意两个顶点之间都存在路径,并且子图中没有任何一个顶点与子图外部的顶点共享边,则称其为 连通分量 。

如果连通分量中每对节点之间都存在一条边,则称其为 完全连通分量 。

示例 1:

输入:n = 6, edges = [[0,1],[0,2],[1,2],[3,4]]
输出:3
解释:如上图所示,可以看到此图所有分量都是完全连通分量。

题目解析:

题目中要求输入一个整数和一个数组,整数代表一共有几个顶点,二维数组表示这几个顶点之间有没有连线。最后要求输出这个顶点中完全连通分量的个数,所谓的完全连通分量是指几个顶点之间相互连接,没有任何一个顶点与子图外部的顶点共享边。也就是要围成一个圈。

当读完题第一时间想到的方法就是使用并查集的方式找出分量的数量,再去判断该分量是不是完全连通分量。

并查集的方法再此就不多做解释了,具体可见我的另一篇博客,里面我具体介绍了并查集算法的思想以及实现。

LeetCode547——省份数量(并查集)

当实现完并查集后,我们就可以得到连通分量的个数,之后我们就要去判断该连通分量是不是完全连通分量了。

这里需要用到一些数学的思维,我们可以通过整个图中边和点的数量来判断该图是不是完全连通分量,如果图中有m个顶点,有n条边,当n=m*(m-1)/2时。因为每个节点都要与其他的节点具有边,因此要m*(m-1),但是这样会重复统计,因此还要除以2.所以当边和顶点数满足此关系时,其就是个完全连通分量。就像当有四个顶点时,应有下图:

所以下面我们就要拿到每个连通分量中的顶点数和边数。这里我用了两个哈希表来表示。

用哈希表的key表示连通图的序号,用value表示拥有的点和边。

首先遍历p数组,数组中表示每个顶点的父节点,一个父节点就可以表示一个连通图,因为一个连通图的父节点都是一样的,如果其父节点存在,那么把该点加到该连通分量中,否则再哈希表中新加入一个key值。

但是由于本题中一个节点可能会连接3个乃至更多的节点,并且连接结构可能比较复杂,所以最后得到的数组中可能并不完善,可能会有间接的父节点,就比如我们可能会得到数组{1,2,2,2},这个是存在间接父节点的,第0个节点的父节点是1,第一个元素的父节点就2.这个数组就等价于{2,2,2,2}。

因此我们不能直接用p[i]来找到其真正的父节点,要再次使用一次find方法才能找到其真正的父节点。

在寻找边时我们就可以直接遍历输入的二维数组,将边的数量放入到哈希表中。

最后我们再次遍历节点,找到每个节点的父节点,根据哈希表得到边和顶点的数量进行判断,当一个父节点判断过后就将设设为-1,在循环中遇到-1直接跳到下一次循环,因为等于-1时该连通分量已经计算过了。遍历结束后我们就得到了答案。

代码实现:

class Solution {
    public int countCompleteComponents(int n, int[][] edges) {
        int len = edges.length;
        int[] p = new int[n];
        for(int i=0;i<n;i++){
            p[i]=i;
        }
        for(int j=0;j<len;j++){
            union(p,edges[j][0],edges[j][1]);
        }
        Map<Integer,Integer> map = new HashMap<>();
        for(int k =0;k<n;k++){
            int f = find(p,k);
            if(!map.containsKey(f)){
                map.put(f,1);
            }else{
                map.put(f,map.get(f)+1);
            }
        }
        Map<Integer,Integer> s = new HashMap<>();
        for(int i=0;i<n;i++){
            s.put(i,0);
        }
        for(int i=0;i<len;i++){
            int key = find(p,edges[i][0]);
            s.put(key,s.get(key)+1);
        }
        int res=0;
        for(int i=0;i<n;i++){
            int x = map.get(p[i]);
            if(x==-1){
                continue;
            }
            if(s.get(p[i])==(x*(x-1))/2) res++;
            map.put(p[i],-1);
        }
        return res;
    }
    public void union(int[] p,int index1,int index2){
        p[find(p,index1)]=find(p,index2);
    }
    public int find(int[] p,int index){
        if(p[index]!=index){
            p[index]=find(p,p[index]);
        }
        return p[index];
    }
}

相关推荐

  1. 力扣2799.统计完全子数组数目

    2024-04-02 14:34:08       36 阅读
  2. 数据统计探针:SKlearn中统计分析方法

    2024-04-02 14:34:08       26 阅读
  3. mysql统计连续出现数字

    2024-04-02 14:34:08       33 阅读
  4. LeetCode 2824.统计和小于目标下标对数目

    2024-04-02 14:34:08       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-02 14:34:08       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-02 14:34:08       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-02 14:34:08       87 阅读
  4. Python语言-面向对象

    2024-04-02 14:34:08       96 阅读

热门阅读

  1. C语言归并递归与非递归实现

    2024-04-02 14:34:08       36 阅读
  2. 1187: 【二维数组】矩阵加法

    2024-04-02 14:34:08       36 阅读
  3. 开发基础知识之应用程序包基础知识

    2024-04-02 14:34:08       34 阅读
  4. 网络问题排查方案(IP冲突问题)

    2024-04-02 14:34:08       34 阅读
  5. Lua脚本的使用

    2024-04-02 14:34:08       38 阅读
  6. react--常见hook

    2024-04-02 14:34:08       38 阅读
  7. 25.死锁

    25.死锁

    2024-04-02 14:34:08      44 阅读
  8. Git 实战教程

    2024-04-02 14:34:08       45 阅读
  9. 数据流模型——【数据科学与工程算法基础】

    2024-04-02 14:34:08       39 阅读
  10. CPU狂飙900%,该怎么处理

    2024-04-02 14:34:08       37 阅读
  11. 【OpenCV进阶】图像中添加中文字幕

    2024-04-02 14:34:08       38 阅读
  12. 低代码与系统集成:革新企业应用开发的新动力

    2024-04-02 14:34:08       38 阅读
  13. MYSQL08_页的概述、内部结构、行格式

    2024-04-02 14:34:08       44 阅读