LeetCode - Clone Graph(圖的克隆)
題目描述
給定一個無向連通圖的引用,請你返回該圖的深拷貝(克隆)。圖中的每個節點包含一個唯一的值 val
和一個列表 neighbors
,表示與其相鄰的節點。
例子:
1
2
3
4
5
6
7
8
輸入:adjList = [[2,4],[1,3],[2,4],[1,3]]
輸出:[[2,4],[1,3],[2,4],[1,3]]
解釋:
1 -- 2
| |
4 -- 3
原圖表示一個四個節點的無向連通圖,其中每個節點的 `val` 分別為 1, 2, 3, 和 4。
返回的應該是該圖的深拷貝,其結構和節點連接方式應與原圖相同。
解法思路
這個問題的核心是創建一個圖的深拷貝,即創建新節點和原節點具有相同的結構和連接,但不是直接引用原節點。
方法:深度優先搜索(DFS) 或 廣度優先搜索(BFS)
可以使用深度優先搜索(DFS)或廣度優先搜索(BFS)來遍歷圖,同時克隆每個節點。
字典記錄節點映射:用一個字典
cloned_nodes
存儲已克隆的節點,以避免重複克隆和循環引用。鍵為原節點,值為克隆後的節點。- DFS/BFS 克隆圖:
- 如果節點已經克隆過,直接返回克隆節點。
- 否則,創建一個新的節點,並將其添加到
cloned_nodes
。 - 遍歷當前節點的相鄰節點並遞歸克隆,將克隆後的相鄰節點添加到新節點的
neighbors
列表中。
- 返回克隆後的起始節點:最終返回克隆圖的起始節點。
範例代碼
以下是使用 DFS 的 Python 實現:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Node:
def __init__(self, val=0, neighbors=None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
def cloneGraph(node):
if not node:
return None
# 使用字典記錄克隆的節點
cloned_nodes = {}
def dfs(node):
# 如果節點已經克隆過,直接返回克隆的節點
if node in cloned_nodes:
return cloned_nodes[node]
# 克隆當前節點(僅複製值,不複製鄰居)
clone = Node(node.val)
cloned_nodes[node] = clone
# 克隆鄰居節點並加入新節點的鄰居列表
for neighbor in node.neighbors:
clone.neighbors.append(dfs(neighbor))
return clone
return dfs(node)
代碼解析
cloned_nodes
字典:記錄已經克隆過的節點,以避免重複克隆。- DFS 函數:每次調用時,檢查當前節點是否已克隆。
- 若未克隆,創建新的節點並遞歸克隆其鄰居,將克隆的鄰居添加到新節點的
neighbors
列表中。
- 若未克隆,創建新的節點並遞歸克隆其鄰居,將克隆的鄰居添加到新節點的
- 返回結果:返回克隆後的整個圖的起始節點。
時間和空間複雜度
- 時間複雜度:O(N),其中
N
是圖中節點的數量。每個節點僅訪問一次。 - 空間複雜度:O(N),由於遞歸棧和
cloned_nodes
字典需要額外空間。
本文章以 CC BY 4.0 授權