• 【每日一题Day354】LC2316统计无向图中无法互相到达点对数 | 并查集


    统计无向图中无法互相到达点对数【LC2316】

    给你一个整数 n ,表示一张 无向图 中有 n 个节点,编号为 0n - 1 。同时给你一个二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示节点 aibi 之间有一条 无向 边。

    请你返回 无法互相到达 的不同 点对数目

    • 思路

      • **并查集查找连通性:**记录每个点的父节点,父节点相同的节点可以相互到达;与父节点不同的节点,不可以互相到达
      • 计算数量,父节点为 i i i的节点数量为 a a a,那么这个节点与 n − a n-a na个节点不相邻,统计数量
      • 统计结果,由于重复计算,最终结果需要除以2
    • 实现

      class Solution {
          public long countPairs(int n, int[][] edges) {
              // 并查集记录每个点的父节点,父节点相同的节点可以相互到达;与父节点不同的节点,不可以互相到达
              // 计算数量,父节点为i的节点数量为a,那么这个节点与n-a个节点不相邻,统计数量
              // 统计结果,由于重复计算,最终结果需要除以2
              UnionFind union = new UnionFind(n);
              for (int[] edge : edges){
                  union.union(edge[0], edge[1]);
              }
              long res = 0L;
              for (int i = 0; i < n; i++){
                  res += n - union.getSize(i);
              }
              return res / 2;
      
          }
      }
      // 并查集类
      class UnionFind {
          private int[] p;// 父节点
          private int[] size;// 每个节点的子节点个数(包括自身)
      	// 初始化
          public UnionFind(int n) {
              p = new int[n];
              size = new int[n];
              for (int i = 0; i < n; ++i) {
                  p[i] = i;
                  size[i] = 1;
              }
          }
      	// 找到节点x的根
          public int find(int x) {
              if (p[x] != x) {
                  p[x] = find(p[x]);
              }
              return p[x];
          }
      	// 在并查集中加入a->b的根
          public void union(int a, int b) {
              int pa = find(a), pb = find(b);
              if (pa != pb) {
                  if (size[pa] > size[pb]) {
                      p[pb] = pa;
                      size[pa] += size[pb];
                  } else {
                      p[pa] = pb;
                      size[pb] += size[pa];
                  }
              }
          }
          public int getSize(int a){
              int father = find(a);
              return size[father];
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 复杂度分析
        • 时间复杂度: O ( n + α ( m ) ∗ m ) O(n+\alpha (m)*m) O(n+α(m)m) n n n为图中顶点的数目, m m m为图中边的数目。其中 α \alpha α为阿克曼函数的反函数,其增长极其缓慢,也就是说其单次操作的平均运行时间可以认为是一个很小的常数。
        • 空间复杂度: O ( n ) O(n) O(n),空间复杂度主要取决于并查集,并查集需要 O ( n ) O(n) O(n)的空间,因此总的空间复杂度为 O ( n ) O(n) O(n)
  • 相关阅读:
    2022年五款适合新手入门的吉他推荐,超全面吉他选购攻略防雷不踩坑!
    windows下安装Mongodb
    Linux中的库(静态库和动态库)详解
    梳理promise功能逻辑,手写promise及相关方法
    javascript中Uint8/16/32Array 传入负数问题
    博客摘录「 YOLOv5模型剪枝压缩」2024年5月11日
    OPT华东产业园封顶,机器视觉产业版图再扩大!
    Lua更多语法与使用
    harib09c的编译和调试
    C语言程序的编译(预处理)概述 —— 上
  • 原文地址:https://blog.csdn.net/Tikitian/article/details/133961919