标签:
Clone an undirected graph. Each node in the graph contains a label
and a list of its neighbors
.
Nodes are labeled uniquely.
We use#
as a separator for each node, and ,
as a separator for node label and each neighbor 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 #
.
0
. Connect node 0
to both nodes 1
and 2
.1
. Connect node 1
to node 2
.2
. Connect node 2
to node 2
(itself), thus forming a self-cycle.Visually, the graph looks like the following:
1 / / 0 --- 2 / \_/
This is a classic question which can be solved by DFS and BFS.
Review for DFS and BFS on Graph.
We can use BFS to traverse original graph, and create new graph.
1. Classic way to implement BFS is by queue. There is another class in Java, LinkedList, which has both list and deque‘s interface. It can also act as queue.
2. We also need to record whether a node in original graph has been visited. When a node in original graph was visited, it means that a node in new graph was created. Therefore, we create a map to record.
Time complexity O(n), space cost O(n)
1 /** 2 * Definition for undirected graph. 3 * class UndirectedGraphNode { 4 * int label; 5 * List<UndirectedGraphNode> neighbors; 6 * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); } 7 * }; 8 */ 9 public class Solution { 10 public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { 11 if (node == null) 12 return null; 13 UndirectedGraphNode newHead = new UndirectedGraphNode(node.label); 14 // Create a queue for BFS 15 LinkedList<UndirectedGraphNode> ll = new LinkedList<UndirectedGraphNode>(); 16 ll.add(node); 17 // Create a map to record visited nodes 18 Map<UndirectedGraphNode, UndirectedGraphNode> hm = new HashMap<UndirectedGraphNode, UndirectedGraphNode>(); 19 hm.put(node, newHead); 20 while (ll.size() > 0) { 21 UndirectedGraphNode tmpNode = ll.remove(); 22 UndirectedGraphNode currentNode = hm.get(tmpNode); 23 List<UndirectedGraphNode> neighbors = tmpNode.neighbors; 24 for (UndirectedGraphNode neighbor : neighbors) { 25 if (!hm.containsKey(neighbor)) { 26 // If the neighbor node is not visited, add it to the list, hashmap and current node‘s neighbor 27 UndirectedGraphNode copy = new UndirectedGraphNode(neighbor.label); 28 currentNode.neighbors.add(copy); 29 ll.add(neighbor); 30 hm.put(neighbor, copy); 31 } else { 32 // If the neighbor node is already visited, just add it to current node‘s neighbor 33 UndirectedGraphNode copy = hm.get(neighbor); 34 currentNode.neighbors.add(copy); 35 } 36 } 37 } 38 return newHead; 39 } 40 }
Usually, we use recursion to implement DFS. We also need a map to record whether a node has been visited. Time complexity O(n), space cost O(n).
1 /** 2 * Definition for undirected graph. 3 * class UndirectedGraphNode { 4 * int label; 5 * List<UndirectedGraphNode> neighbors; 6 * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); } 7 * }; 8 */ 9 public class Solution { 10 public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { 11 if (node == null) 12 return null; 13 UndirectedGraphNode newHead = new UndirectedGraphNode(node.label); 14 Map<UndirectedGraphNode, UndirectedGraphNode> hm = new HashMap<UndirectedGraphNode, UndirectedGraphNode>(); 15 hm.put(node, newHead); 16 DFS(hm, node); 17 return newHead; 18 } 19 20 private void DFS(Map<UndirectedGraphNode, UndirectedGraphNode> hm, UndirectedGraphNode node) { 21 UndirectedGraphNode currentNode = hm.get(node); 22 List<UndirectedGraphNode> neighbors = node.neighbors; 23 for (UndirectedGraphNode neighbor : neighbors) { 24 if (!hm.containsKey(neighbor)) { 25 UndirectedGraphNode copy = new UndirectedGraphNode(neighbor.label); 26 currentNode.neighbors.add(copy); 27 hm.put(neighbor, copy); 28 DFS(hm, neighbor); 29 } else { 30 UndirectedGraphNode copy = hm.get(neighbor); 31 currentNode.neighbors.add(copy); 32 } 33 } 34 } 35 }
标签:
原文地址:http://www.cnblogs.com/ireneyanglan/p/4834258.html