133 Clone Graph Medium
考察对图的遍历和利用HashMap拷贝的方法。
图的遍历就是两个经典的方法:DFS和BFS。
BFS经常用Queue实现,DFS经常用递归实现(可改为栈实现)。
拷贝方法是用HashMap,key存原始值,value存copy的值,用DFS,BFS方法遍历帮助拷贝neighbors的值。
-
DFS 递归
Input: A graph G and a root v of G procedure DFS(G,v): label v as discovered for all edges from v to w in G.adjacentEdges(v) do if vertex w is not labeled as discovered then recursively call DFS(G,w)/** * Definition for undirected graph. * class UndirectedGraphNode { * int label; * List<UndirectedGraphNode> neighbors; * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); } * }; */ public class Solution { public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if(node == null) { return null; } Map<UndirectedGraphNode, UndirectedGraphNode> hashmap = new HashMap<>(); UndirectedGraphNode copy = new UndirectedGraphNode(node.label); hashmap.put(node,copy); DFS(hashmap, node); //递归 return copy; } private void DFS(Map<UndirectedGraphNode, UndirectedGraphNode> hashmap, UndirectedGraphNode node) { if(node == null) { return; } for(UndirectedGraphNode neighbor:node.neighbors) { if(!hashmap.containsKey(neighbor)) { UndirectedGraphNode copyNeighbor = new UndirectedGraphNode(neighbor.label); hashmap.put(neighbor, copyNeighbor); DFS(hashmap, neighbor); } hashmap.get(node).neighbors.add(hashmap.get(neighbor)); } } } -
DFS 非递归
Input: A graph G and a root v of G procedure DFS-iterative(G,v): let S be a stack label v as discovered S.push(v) while S is not empty v ← S.pop() if v is not labeled as discovered: label v as discovered for all edges from v to w in G.adjacentEdges(v) do S.push(w)/** * Definition for undirected graph. * class UndirectedGraphNode { * int label; * List<UndirectedGraphNode> neighbors; * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); } * }; */ public class Solution { public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if(node == null) { return null; } Deque<UndirectedGraphNode> stack = new ArrayDeque<>(); Map<UndirectedGraphNode, UndirectedGraphNode> hashmap = new HashMap<>(); UndirectedGraphNode copy = new UndirectedGraphNode(node.label); hashmap.put(node,copy); stack.addFirst(node); while(!stack.isEmpty()) { UndirectedGraphNode v = stack.removeFirst(); for(UndirectedGraphNode neighbor:v.neighbors) { if(!hashmap.containsKey(neighbor)) { UndirectedGraphNode copyNeighbor = new UndirectedGraphNode(neighbor.label); hashmap.put(neighbor, copyNeighbor); stack.addFirst(neighbor); } hashmap.get(v).neighbors.add(hashmap.get(neighbor)); } } return copy; } } -
BFS 队列
对于一个节点来说先把所有neighbors都检查一遍,再从第一个neighbor开始,循环往复。 BFS可以帮助寻找最短路径。
Input: A graph G and a root v of G
procedure BFS(G,v) is
create a queue Q
label v as discovered
enqueue v onto Q
while Q is not empty
v ← Q.dequeue()
for all edges from v to w in G.adjacentEdges(v) do
if vertex w is not labeled as discovered then
label w as discovered
enqueue w onto Q
/**
* Definition for undirected graph.
* class UndirectedGraphNode {
* int label;
* List<UndirectedGraphNode> neighbors;
* UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
* };
*/
public class Solution {
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
if(node == null) {
return null;
}
LinkedList<UndirectedGraphNode> queue = new LinkedList<>();
Map<UndirectedGraphNode, UndirectedGraphNode> hashmap = new HashMap<>();
UndirectedGraphNode copy = new UndirectedGraphNode(node.label);
hashmap.put(node,copy);
queue.add(node);
while(!queue.isEmpty()) {
UndirectedGraphNode v = queue.remove();
for(UndirectedGraphNode neighbor:v.neighbors) {
if(!hashmap.containsKey(neighbor)) {
UndirectedGraphNode copyNeighbor = new UndirectedGraphNode(neighbor.label);
hashmap.put(neighbor, copyNeighbor);
queue.add(neighbor);
}
hashmap.get(v).neighbors.add(hashmap.get(neighbor));
}
}
return copy;
}
}