@@ -92,7 +92,20 @@ class Node {
9292
9393<!-- solution:start -->
9494
95- ### 方法一
95+ ### 方法一:哈希表 + DFS
96+
97+ 我们用一个哈希表 $\textit{g}$ 记录原图中的每个节点和它的拷贝节点之间的对应关系,然后进行深度优先搜索。
98+
99+ 我们定义函数 $\text{dfs}(node)$,它的功能是返回 $\textit{node}$ 节点的拷贝节点。$\text{dfs}(node)$ 的过程如下:
100+
101+ - 如果 $\textit{node}$ 是 $\text{null}$,那么 $\text{dfs}(node)$ 的返回值是 $\text{null}$。
102+ - 如果 $\textit{node}$ 在 $\textit{g}$ 中,那么 $\text{dfs}(node)$ 的返回值是 $\textit{g}[ node] $。
103+ - 否则我们创建一个新的节点 $\textit{cloned}$,并将 $\textit{g}[ node] $ 的值设为 $\textit{cloned}$,然后遍历 $\textit{node}$ 的所有邻居节点 $\textit{nxt}$,并将 $\textit{cloned}$ 的邻居节点列表中加入 $\text{dfs}(nxt)$。
104+ - 最后返回 $\textit{cloned}$。
105+
106+ 在主函数中,我们返回 $\text{dfs}(node)$。
107+
108+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是节点的数量。
96109
97110<!-- tabs:start -->
98111
@@ -107,23 +120,24 @@ class Node:
107120 self.neighbors = neighbors if neighbors is not None else []
108121"""
109122
123+ from typing import Optional
110124
111- class Solution :
112- def cloneGraph (self , node : ' Node' ) -> ' Node' :
113- visited = defaultdict()
114125
115- def clone (node ):
126+ class Solution :
127+ def cloneGraph (self , node : Optional[" Node" ]) -> Optional[" Node" ]:
128+ def dfs (node ):
116129 if node is None :
117130 return None
118- if node in visited:
119- return visited[node]
120- c = Node(node.val)
121- visited[node] = c
122- for e in node.neighbors:
123- c.neighbors.append(clone(e))
124- return c
125-
126- return clone(node)
131+ if node in g:
132+ return g[node]
133+ cloned = Node(node.val)
134+ g[node] = cloned
135+ for nxt in node.neighbors:
136+ cloned.neighbors.append(dfs(nxt))
137+ return cloned
138+
139+ g = defaultdict()
140+ return dfs(node)
127141```
128142
129143#### Java
@@ -150,21 +164,25 @@ class Node {
150164*/
151165
152166class Solution {
153- private Map<Node , Node > visited = new HashMap<> ();
167+ private Map<Node , Node > g = new HashMap<> ();
154168
155169 public Node cloneGraph (Node node ) {
170+ return dfs(node);
171+ }
172+
173+ private Node dfs (Node node ) {
156174 if (node == null ) {
157175 return null ;
158176 }
159- if (visited . containsKey (node)) {
160- return visited . get(node);
161- }
162- Node clone = new Node (node. val );
163- visited . put(node, clone);
164- for ( Node e : node . neighbors) {
165- clone . neighbors . add(cloneGraph(e));
177+ Node cloned = g . get (node);
178+ if (cloned == null ) {
179+ cloned = new Node (node . val);
180+ g . put (node, cloned );
181+ for ( Node nxt : node . neighbors) {
182+ cloned . neighbors. add(dfs(nxt));
183+ }
166184 }
167- return clone ;
185+ return cloned ;
168186 }
169187}
170188```
@@ -195,16 +213,23 @@ public:
195213
196214class Solution {
197215public:
198- unordered_map<Node* , Node* > visited;
199-
200216 Node* cloneGraph(Node* node) {
201- if (!node) return nullptr;
202- if (visited.count(node)) return visited[node];
203- Node* clone = new Node(node->val);
204- visited[node] = clone;
205- for (auto& e : node->neighbors)
206- clone->neighbors.push_back(cloneGraph(e));
207- return clone;
217+ unordered_map<Node* , Node* > g;
218+ auto dfs = [ &] (this auto&& dfs, Node* node) -> Node* {
219+ if (!node) {
220+ return nullptr;
221+ }
222+ if (g.contains(node)) {
223+ return g[ node] ;
224+ }
225+ Node* cloned = new Node(node->val);
226+ g[ node] = cloned;
227+ for (auto& nxt : node->neighbors) {
228+ cloned->neighbors.push_back(dfs(nxt));
229+ }
230+ return cloned;
231+ };
232+ return dfs(node);
208233 }
209234};
210235```
@@ -221,99 +246,142 @@ public:
221246 */
222247
223248func cloneGraph(node *Node) *Node {
224- visited := map [*Node]*Node{}
225- var clone func (node *Node) *Node
226- clone = func (node *Node) *Node {
249+ g := map[*Node]*Node{}
250+ var dfs func(node *Node) *Node
251+ dfs = func(node *Node) *Node {
227252 if node == nil {
228253 return nil
229254 }
230- if _ , ok := visited [node]; ok {
231- return visited[node]
255+ if n , ok := g [node]; ok {
256+ return n
232257 }
233- c := &Node{node.Val , []*Node{}}
234- visited [node] = c
235- for _ , e := range node.Neighbors {
236- c .Neighbors = append (c .Neighbors , clone (e ))
258+ cloned := &Node{node.Val, []*Node{}}
259+ g [node] = cloned
260+ for _, nxt := range node.Neighbors {
261+ cloned .Neighbors = append(cloned .Neighbors, dfs(nxt ))
237262 }
238- return c
263+ return cloned
239264 }
240-
241- return clone (node)
265+ return dfs(node)
242266}
243267```
244268
245269#### TypeScript
246270
247271``` ts
248272/**
249- * Definition for Node .
250- * class Node {
273+ * Definition for _Node .
274+ * class _Node {
251275 * val: number
252- * neighbors: Node[]
253- * constructor(val?: number, neighbors?: Node[]) {
276+ * neighbors: _Node[]
277+ *
278+ * constructor(val?: number, neighbors?: _Node[]) {
254279 * this.val = (val===undefined ? 0 : val)
255280 * this.neighbors = (neighbors===undefined ? [] : neighbors)
256281 * }
257282 * }
283+ *
258284 */
259285
260- function cloneGraph(node : Node | null ): Node | null {
261- if (node == null ) return null ;
262-
263- const visited = new Map ();
264- visited .set (node , new Node (node .val ));
265- const queue = [node ];
266- while (queue .length ) {
267- const cur = queue .shift ();
268- for (let neighbor of cur .neighbors || []) {
269- if (! visited .has (neighbor )) {
270- queue .push (neighbor );
271- const newNeighbor = new Node (neighbor .val , []);
272- visited .set (neighbor , newNeighbor );
273- }
274- const newNode = visited .get (cur );
275- newNode .neighbors .push (visited .get (neighbor ));
286+ function cloneGraph(node : _Node | null ): _Node | null {
287+ const g: Map <_Node , _Node > = new Map ();
288+ const dfs = (node : _Node | null ): _Node | null => {
289+ if (! node ) {
290+ return null ;
276291 }
277- }
278- return visited .get (node );
292+ if (g .has (node )) {
293+ return g .get (node );
294+ }
295+ const cloned = new _Node (node .val );
296+ g .set (node , cloned );
297+ for (const nxt of node .neighbors ) {
298+ cloned .neighbors .push (dfs (nxt ));
299+ }
300+ return cloned ;
301+ };
302+ return dfs (node );
279303}
280304```
281305
306+ #### JavaScript
307+
308+ ``` js
309+ /**
310+ * // Definition for a _Node.
311+ * function _Node(val, neighbors) {
312+ * this.val = val === undefined ? 0 : val;
313+ * this.neighbors = neighbors === undefined ? [] : neighbors;
314+ * };
315+ */
316+
317+ /**
318+ * @param {_Node} node
319+ * @return {_Node}
320+ */
321+ var cloneGraph = function (node ) {
322+ const g = new Map ();
323+ const dfs = node => {
324+ if (! node) {
325+ return null ;
326+ }
327+ if (g .has (node)) {
328+ return g .get (node);
329+ }
330+ const cloned = new _Node (node .val );
331+ g .set (node, cloned);
332+ for (const nxt of node .neighbors ) {
333+ cloned .neighbors .push (dfs (nxt));
334+ }
335+ return cloned;
336+ };
337+ return dfs (node);
338+ };
339+ ```
340+
282341#### C#
283342
284343``` cs
285- using System .Collections .Generic ;
344+ /*
345+ // Definition for a Node.
346+ public class Node {
347+ public int val;
348+ public IList<Node> neighbors;
349+
350+ public Node() {
351+ val = 0;
352+ neighbors = new List<Node>();
353+ }
354+
355+ public Node(int _val) {
356+ val = _val;
357+ neighbors = new List<Node>();
358+ }
359+
360+ public Node(int _val, List<Node> _neighbors) {
361+ val = _val;
362+ neighbors = _neighbors;
363+ }
364+ }
365+ */
286366
287367public class Solution {
288368 public Node CloneGraph (Node node ) {
289- if (node == null ) return null ;
290- var dict = new Dictionary <int , Node >();
291- var queue = new Queue <Node >();
292- queue .Enqueue (CloneVal (node ));
293- dict .Add (node .val , queue .Peek ());
294- while (queue .Count > 0 )
295- {
296- var current = queue .Dequeue ();
297- var newNeighbors = new List <Node >(current .neighbors .Count );
298- foreach (var oldNeighbor in current .neighbors )
299- {
300- Node newNeighbor ;
301- if (! dict .TryGetValue (oldNeighbor .val , out newNeighbor ))
302- {
303- newNeighbor = CloneVal (oldNeighbor );
304- queue .Enqueue (newNeighbor );
305- dict .Add (newNeighbor .val , newNeighbor );
306- }
307- newNeighbors .Add (newNeighbor );
369+ var g = new Dictionary <Node , Node >();
370+ Node Dfs (Node n ) {
371+ if (n == null ) {
372+ return null ;
373+ }
374+ if (g .ContainsKey (n )) {
375+ return g [n ];
308376 }
309- current .neighbors = newNeighbors ;
377+ var cloned = new Node (n .val );
378+ g [n ] = cloned ;
379+ foreach (var neighbor in n .neighbors ) {
380+ cloned .neighbors .Add (Dfs (neighbor ));
381+ }
382+ return cloned ;
310383 }
311- return dict [node .val ];
312- }
313-
314- private Node CloneVal (Node node )
315- {
316- return new Node (node .val , new List <Node >(node .neighbors ));
384+ return Dfs (node );
317385 }
318386}
319387```
0 commit comments