Clone Graph

描述

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbours.

OJ's undirected graph serialization:Nodes are labeled uniquely.

We use # as a separator for each node, and , as a separator for node label and each neighbour of the node.As an example, consider the serialized graph {0,1,2#1,2#2,2}.

The graph has a total of three nodes, and therefore contains three parts as separated by #.

  • First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
  • Second node is labeled as 1. Connect node 1 to node 2.
  • Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.
    Visually, the graph looks like the following:
  1. 1
  2. / \
  3. / \
  4. 0 --- 2
  5. / \
  6. \_/

分析

广度优先遍历或深度优先遍历都可以。

DFS

  1. // Clone Graph
  2. // DFS,时间复杂度O(n),空间复杂度O(n)
  3. public class Solution {
  4. public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
  5. if(node == null) return null;
  6. // key is original node,value is copied node
  7. HashMap<UndirectedGraphNode, UndirectedGraphNode> visited = new HashMap<>();
  8. clone(node, visited);
  9. return visited.get(node);
  10. }
  11. // DFS
  12. private static UndirectedGraphNode clone(UndirectedGraphNode node,
  13. HashMap<UndirectedGraphNode,
  14. UndirectedGraphNode> visited) {
  15. // a copy already exists
  16. if (visited.containsKey(node)) return visited.get(node);
  17. UndirectedGraphNode new_node = new UndirectedGraphNode(node.label);
  18. visited.put(node, new_node);
  19. for (UndirectedGraphNode nbr : node.neighbors)
  20. new_node.neighbors.add(clone(nbr, visited));
  21. return new_node;
  22. }
  23. }

BFS

  1. // Clone Graph
  2. // BFS,时间复杂度O(n),空间复杂度O(n)
  3. public class Solution {
  4. public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
  5. if (node == null) return null;
  6. // key is original node,value is copied node
  7. HashMap<UndirectedGraphNode,UndirectedGraphNode> visited = new HashMap<>();
  8. // each node in queue is already copied itself
  9. // but neighbors are not copied yet
  10. Queue<UndirectedGraphNode> q = new LinkedList<>();
  11. q.offer(node);
  12. visited.put(node, new UndirectedGraphNode(node.label));
  13. while (!q.isEmpty()) {
  14. UndirectedGraphNode cur = q.poll();
  15. for (UndirectedGraphNode nbr : cur.neighbors) {
  16. // a copy already exists
  17. if (visited.containsKey(nbr)) {
  18. visited.get(cur).neighbors.add(visited.get(nbr));
  19. } else {
  20. UndirectedGraphNode new_node =
  21. new UndirectedGraphNode(nbr.label);
  22. visited.put(nbr, new_node);
  23. visited.get(cur).neighbors.add(new_node);
  24. q.offer(nbr);
  25. }
  26. }
  27. }
  28. return visited.get(node);
  29. }
  30. }

原文: https://soulmachine.gitbooks.io/algorithm-essentials/content/java/graph/clone-graph.html