zoukankan      html  css  js  c++  java
  • [LeetCode] 323. Number of Connected Components in an Undirected Graph

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to find the number of connected components in an undirected graph.

    Example 1:

    Input: n = 5 and edges = [[0, 1], [1, 2], [3, 4]]
    
         0          3
         |          |
         1 --- 2    4 
    
    Output: 2
    

    Example 2:

    Input: n = 5 and edges = [[0, 1], [1, 2], [2, 3], [3, 4]]
    
         0           4
         |           |
         1 --- 2 --- 3
    
    Output:  1
    

    Note:
    You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

    无向图中连通分量的数目。

    给定编号从 0 到 n-1 的 n 个节点和一个无向边列表(每条边都是一对节点),请编写一个函数来计算无向图中连通分量的数目。

    注意:
    你可以假设在 edges 中不会出现重复的边。而且由于所以的边都是无向边,[0, 1] 与 [1, 0]  相同,所以它们不会同时在 edges 中出现。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/number-of-connected-components-in-an-undirected-graph
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    这道题可以归结为flood fill类型的题,我这里给出三种解法,分别是BFS, DFS和并查集union find。其中DFS和并查集是需要重点掌握的,BFS的复杂度略高。

    BFS

    时间O(n^2)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int countComponents(int n, int[][] edges) {
     3         int count = 0;
     4         List<List<Integer>> g = new ArrayList<>();
     5         boolean[] visited = new boolean[n];
     6         for (int i = 0; i < n; i++) {
     7             g.add(new ArrayList<>());
     8         }
     9         for (int[] e : edges) {
    10             g.get(e[0]).add(e[1]);
    11             g.get(e[1]).add(e[0]);
    12         }
    13 
    14         for (int i = 0; i < n; i++) {
    15             if (!visited[i]) {
    16                 count++;
    17                 Queue<Integer> queue = new LinkedList<>();
    18                 queue.offer(i);
    19                 while (!queue.isEmpty()) {
    20                     int index = queue.poll();
    21                     visited[index] = true;
    22                     for (int next : g.get(index)) {
    23                         if (!visited[next]) {
    24                             queue.offer(next);
    25                         }
    26                     }
    27                 }
    28             }
    29         }
    30         return count;
    31     }
    32 }

    DFS

    时间O(n^2)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int countComponents(int n, int[][] edges) {
     3         int count = 0;
     4         List<List<Integer>> g = new ArrayList<>();
     5         boolean[] visited = new boolean[n];
     6         for (int i = 0; i < n; i++) {
     7             g.add(new ArrayList<>());
     8         }
     9         for (int[] e : edges) {
    10             g.get(e[0]).add(e[1]);
    11             g.get(e[1]).add(e[0]);
    12         }
    13 
    14         for (int i = 0; i < n; i++) {
    15             if (!visited[i]) {
    16                 count++;
    17                 dfs(visited, i, g);
    18             }
    19         }
    20         return count;
    21     }
    22 
    23     private void dfs(boolean[] visited, int index, List<List<Integer>> g) {
    24         visited[index] = true;
    25         for (int i : g.get(index)) {
    26             if (!visited[i]) {
    27                 dfs(visited, i, g);
    28             }
    29         }
    30     }
    31 }

    Union Find

    时间O(V * E)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int countComponents(int n, int[][] edges) {
     3         int count = n;
     4         int[] parents = new int[n];
     5         for (int i = 0; i < n; i++) {
     6             parents[i] = i;
     7         }
     8         for (int[] edge : edges) {
     9             int p = find(parents, edge[0]);
    10             int q = find(parents, edge[1]);
    11             if (p != q) {
    12                 parents[p] = q;
    13                 count--;
    14             }
    15         }
    16         return count;
    17     }
    18 
    19     private int find(int[] parents, int i) {
    20         while (parents[i] != i) {
    21             parents[i] = parents[parents[i]]; // 路径压缩
    22             i = parents[i];
    23         }
    24         return i;
    25     }
    26 }

    相关题目

    261. Graph Valid Tree

    323. Number of Connected Components in an Undirected Graph

    547. Friend Circles

    LeetCode 题目总结

  • 相关阅读:
    Java实现 LeetCode 30 串联所有单词的子串
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 27 移除元素
    字符编码终极笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14197652.html
Copyright © 2011-2022 走看看