给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。
图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node])。
class Node {
public int val;
public List<Node> neighbors;
}
提示:
节点数不超过 100 。
每个节点值 Node.val 都是唯一的,1 <= Node.val <= 100。
无向图是一个简单图,这意味着图中没有重复的边,也没有自环。
由于图是无向的,如果节点 p 是节点 q 的邻居,那么节点 q 也必须是节点 p 的邻居。
图是连通图,你可以从给定节点访问到所有节点。
该题目主要考察图的遍历,有dfs和bfs两种做法。
dfs:要注意传入的node为空的情况。
递归设计要点:
1、每层只考虑每层的事情,不需要考虑下一层的事情
2、注意basecase的设计
class Solution:
def cloneGraph(self, node: 'Node') -> 'Node':
if not node:
return
clone_dic = dict()
# 此处的字典有两个作用,一个是遍历时是否已经visit过该节点,一个是存储该节点的深拷贝
def dfs(node):
clone_node = Node(node.val, [])
if not node:
return
if node in clone_dic: # 如果该点已经拷贝,则将该点返回即可
return clone_dic[node]
clone_node = Node(node.val, [])
clone_dic[node] = clone_node
for neighbor in node.neighbors:
clone_node.neighbors.append(dfs(neighbor))
return clone_node
return dfs(node)
bfs:
class Solution:
def cloneGraph(self, node: 'Node') -> 'Node':
from collections import deque
visited = dict()
if not node:
return
def _copy(node):
copied_node = Node(node.val, [])
return copied_node
# bfs
q = deque()
q.appendleft(node)
visited[node] = _copy(node)
while q:
front = q.pop()
for neighbor in front.neighbors:
if neighbor not in visited:
visited [neighbor] = _copy(neighbor)
q.appendleft(neighbor)
visited[front].neighbors.append(visited[neighbor])
return visited[node]