-
图的遍历
133. 克隆图-中等
题目概述:深拷贝整个图
题目网址:https://leetcode-cn.com/problems/clone-graph/
题目思路:实际上是遍历整个图,同时进行克隆操作。虽然给定的是一个无向图但其实可以视作是双向图。
【1】作为python要耍流氓的话当然是一句话deepcopy:
return copy.deepcopy(node)
【2】正常操作下思路分两种:
DFS和BFS,图遍历通常离不开这俩兄弟了。同时为了防止多次遍历同一个节点陷入死循环,我们需要对已经遍历过的节点进行记录。因此关键一个在于哈希表,一个在于克隆节点和其他操作的先后问题。
0-使用哈希表存储所有访问过的原节点(key)和克隆节点(value)。用栈-DFS或者用队列-BFS。
1-从给定节点开始遍历图。
2-访问节点,克隆节点,原节点进栈或队列,克隆节点进哈希表。
3-循环从栈或队列取节点:
3.1-根据取出节点访问邻接节点并重复2。
3.2-将克隆出的邻接节点添加入(哈希表中)取出节点的克隆节点的邻接中。
DFS与BFS的区别其实只有一行,他们仅仅是取出节点的方式不同而已。(同时,DFS因为使用了栈,可以很容易的改成递归模式,但我没写)这其实是在搜索策略中的优先策略问题。
时间复杂度:O(N),每个节点只处理一次。
空间复杂度:O(N)。HashMap O(N),栈需要 O(H),队列需要 O(W),其中 H 是图的深度,W 是图的宽度。
class Solution:
def cloneGraph(self, node: 'Node') -> 'Node':
if not node:
return
visited = {}
que = []
visited[node] = Node(val = node.val)
que.append(node)
while que:
# BFS
curr_node = que.pop(0)
# DFS
# curr_node = que.pop(-1)
for neigh_node in curr_node.neighbors:
if neigh_node not in visited:
que.append(neigh_node)
visited[neigh_node] = Node(val = neigh_node.val)
visited[curr_node].neighbors.append(visited[neigh_node])
return visited[node]
ps:克隆有向图,树时代码也都不需要改变,具有一定的通用性。