Skip to content

Commit 1b22bc7

Browse files
authored
feat: add solutions to lc problem: No.0133 (#4162)
1 parent 50ce67e commit 1b22bc7

File tree

9 files changed

+467
-281
lines changed

9 files changed

+467
-281
lines changed

solution/0100-0199/0133.Clone Graph/README.md

+161-93
Original file line numberDiff line numberDiff line change
@@ -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

152166
class 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

196214
class Solution {
197215
public:
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
223248
func 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

287367
public 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

Comments
 (0)