# LeetCode 133：克隆图 Clone Graph

2019.08.18 23:20 546浏览

### 题目：

Given a reference of a node in a connected undirected graph, return a deep copy (clone) of the graph. Each node in the graph contains a val (`int`) and a list (`List[Node]`) of its neighbors.

``````输入：
{"\$id":"1","neighbors":[{"\$id":"2","neighbors":[{"\$ref":"1"},{"\$id":"3","neighbors":[{"\$ref":"2"},{"\$id":"4","neighbors":[{"\$ref":"3"},{"\$ref":"1"}],"val":4}],"val":3}],"val":2},{"\$ref":"4"}],"val":1}

``````

1. 节点数介于 1 到 100 之间。
2. 无向图是一个简单图，这意味着图中没有重复的边，也没有自环。
3. 由于图是无向的，如果节点 p 是节点 q 的邻居，那么节点 q 也必须是节点 p 的邻居。
4. 必须将给定节点的拷贝作为对克隆图的引用返回。

Note:

1. The number of nodes will be between 1 and 100.
2. The undirected graph is a simple graph, which means no repeated edges and no self-loops in the graph.
3. Since the graph is undirected, if node p has node q as neighbor, then node q must have node p as neighbor too.
4. You must return the copy of the given node as a reference to the cloned graph.

### 解题思路：

BFS就需要借助队列实现，DFS可以借助栈也可以直接用递归实现。就这道题而言直接用递归更好一些，无需开辟额外的数据结构空间记录节点。BFS、DFS写法相对固定，建议花点时间一次性理解透，一劳永逸。

Java：

``````class Solution {
public Node cloneGraph(Node node) {
if (node == null) return node;
Map<Node, Node> map = new HashMap<>();//哈希映射
Node head = new Node(node.val, new ArrayList<>());//头节点
while (!queue.isEmpty()) {//队列不为空就重复循环
Node tmp = queue.poll();//弹出队列头节点
for (Node n : tmp.neighbors) {//遍历邻居节点
if (!map.containsKey(n)) {//字典的键不包含该节点时
map.put(n, new Node(n.val, new ArrayList<>()));//新建映射关系加入字典
}
}
}
}
}
``````

Python3：

``````class Solution:
def cloneGraph(self, node: 'Node') -> 'Node':
if not node: return node
queue = collections.deque()#队列
queue.append(node)#原节点加入队列
while queue:#队列不为空
tmp = queue.popleft()#弹出队列头节点
for n in tmp.neighbors:#遍历邻居节点
if n in map.keys():#n节点存在于字典的键里时
map[tmp].neighbors.append(map[n])#直接加入到新节点的邻居节点
else:
map[n] = Node(n.val, [])#新建节点并建立映射关系
map[tmp].neighbors.append(map[n])#由新建的映射关系取出节点并加入邻居节点
queue.append(n)#该邻居节点加入队列
``````

### DFS：

Java：

``````class Solution {
Map<Node, Node> map = new HashMap();

public Node cloneGraph(Node node) {
if (node == null) return node;
map.put(node, new Node(node.val, new ArrayList<>()));//每次都要新建节点并建立映射关系
for (Node n : node.neighbors) {
}
return map.get(node);
}
}
``````

Python3：

``````class Solution:
map = dict()

def cloneGraph(self, node: 'Node') -> 'Node':
if not node: return node
self.map[node] = Node(node.val, [])
for n in node.neighbors:
if n in self.map.keys():
self.map[node].neighbors.append(self.map[n])
else:
self.map[node].neighbors.append(self.cloneGraph(n))
return self.map[node]
``````

python中的字典取values时可以 `dict().get(key)` 也可以 `dict[key]` 时间复杂度都为1，但是在做算法题时肯定要用 `dict[key]` 这种方式。因为 get() 方法虽然效果一样，但是反复调用函数造成的时间消耗非常高，python语言本来就慢，应该养成尽可能优化代码的习惯

1人点赞

• 1
• 评论
• 收藏
• 共同学习，写下你的评论

0/150