Find the Connected Component in the Undirected Graph

Question

Problem Statement

Find the number connected component in the undirected graph. Each node in the
graph contains a label and a list of its neighbors. (a connected component (or
just component) of an undirected graph is a subgraph in which any two vertices
are connected to each other by paths, and which is connected to no additional
vertices in the supergraph.)

Example

Given graph:

  1. A------B C
  2. \ | |
  3. \ | |
  4. \ | |
  5. \ | |
  6. D E

Return {A,B,D}, {C,E}. Since there are two connected component which is
{A,B,D}, {C,E}

题解1 - DFS

深搜加哈希表(因为有环,必须记录节点是否被访问过)

Java

  1. /**
  2. * Definition for Undirected graph.
  3. * class UndirectedGraphNode {
  4. * int label;
  5. * ArrayList<UndirectedGraphNode> neighbors;
  6. * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
  7. * }
  8. */
  9. public class Solution {
  10. /**
  11. * @param nodes a array of Undirected graph node
  12. * @return a connected set of a Undirected graph
  13. */
  14. public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
  15. if (nodes == null || nodes.size() == 0) return null;
  16. List<List<Integer>> result = new ArrayList<List<Integer>>();
  17. Set<UndirectedGraphNode> visited = new HashSet<UndirectedGraphNode>();
  18. for (UndirectedGraphNode node : nodes) {
  19. if (visited.contains(node)) continue;
  20. List<Integer> temp = new ArrayList<Integer>();
  21. dfs(node, visited, temp);
  22. Collections.sort(temp);
  23. result.add(temp);
  24. }
  25. return result;
  26. }
  27. private void dfs(UndirectedGraphNode node,
  28. Set<UndirectedGraphNode> visited,
  29. List<Integer> result) {
  30. // add node into result
  31. result.add(node.label);
  32. visited.add(node);
  33. // node is not connected, exclude by for iteration
  34. // if (node.neighbors.size() == 0 ) return;
  35. for (UndirectedGraphNode neighbor : node.neighbors) {
  36. if (visited.contains(neighbor)) continue;
  37. dfs(neighbor, visited, result);
  38. }
  39. }
  40. }

源码分析

注意题目的输出要求,需要为 Integer 和有序。添加 node 至 result 和 visited 时放一起,且只在 dfs 入口,避免漏解和重解。

复杂度分析

遍历所有节点和边一次,时间复杂度 O(V+E), 记录节点是否被访问,空间复杂度 O(V).

题解2 - BFS

深搜容易爆栈,采用 BFS 较为安全。BFS 中记录已经访问的节点在入队前判断,可有效防止不重不漏。

Java

  1. /**
  2. * Definition for Undirected graph.
  3. * class UndirectedGraphNode {
  4. * int label;
  5. * ArrayList<UndirectedGraphNode> neighbors;
  6. * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
  7. * }
  8. */
  9. public class Solution {
  10. /**
  11. * @param nodes a array of Undirected graph node
  12. * @return a connected set of a Undirected graph
  13. */
  14. public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
  15. if (nodes == null || nodes.size() == 0) return null;
  16. List<List<Integer>> result = new ArrayList<List<Integer>>();
  17. // log visited node before push into queue
  18. Set<UndirectedGraphNode> visited = new HashSet<UndirectedGraphNode>();
  19. for (UndirectedGraphNode node : nodes) {
  20. if (visited.contains(node)) continue;
  21. List<Integer> row = bfs(node, visited);
  22. result.add(row);
  23. }
  24. return result;
  25. }
  26. private List<Integer> bfs(UndirectedGraphNode node,
  27. Set<UndirectedGraphNode> visited) {
  28. List<Integer> row = new ArrayList<Integer>();
  29. Queue<UndirectedGraphNode> q = new LinkedList<UndirectedGraphNode>();
  30. q.offer(node);
  31. visited.add(node);
  32. while (!q.isEmpty()) {
  33. UndirectedGraphNode qNode = q.poll();
  34. row.add(qNode.label);
  35. for (UndirectedGraphNode neighbor : qNode.neighbors) {
  36. if (visited.contains(neighbor)) continue;
  37. q.offer(neighbor);
  38. visited.add(neighbor);
  39. }
  40. }
  41. Collections.sort(row);
  42. return row;
  43. }
  44. }

源码分析

复杂度分析

同题解一。

Reference