Skip to content

Commit fe47049

Browse files
committed
133
1 parent 939679a commit fe47049

File tree

3 files changed

+161
-3
lines changed

3 files changed

+161
-3
lines changed

SUMMARY.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
* [98. Validate Binary Search Tree](leetCode-98-Validate-Binary-Search-Tree.md)
103103
* [99. Recover Binary Search Tree](leetcode-99-Recover-Binary-Search-Tree.md)
104104
* [100. Same Tree](leetcode-100-Same-Tree.md)
105-
* [101 题到 132](leetcode-101-200.md)
105+
* [101 题到 133](leetcode-101-200.md)
106106
* [101. Symmetric Tree](leetcode-101-Symmetric-Tree.md)
107107
* [102. Binary Tree Level Order Traversal](leetcode-102-Binary-Tree-Level-Order-Traversal.md)
108108
* [103. Binary Tree Zigzag Level Order Traversal](leetcode-103-Binary-Tree-Zigzag-Level-Order-Traversal.md)
@@ -134,4 +134,5 @@
134134
* [129. Sum Root to Leaf Numbers](leetcode-129-Sum-Root-to-Leaf-Numbers.md)
135135
* [130*. Surrounded Regions](leetcode-130-Surrounded-Regions.md)
136136
* [131. Palindrome Partitioning](leetcode-131-Palindrome-Partitioning.md)
137-
* [132. Palindrome Partitioning II](leetcode-132-Palindrome-PartitioningII.md)
137+
* [132. Palindrome Partitioning II](leetcode-132-Palindrome-PartitioningII.md)
138+
* [133. Clone Graph](leetcode-133-Clone-Graph.md)

leetcode-101-200.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,6 @@
6060

6161
<a href="leetcode-131-Palindrome-Partitioning.html">131. Palindrome Partitioning</a>
6262

63-
<a href="leetcode-132-Palindrome-PartitioningII.html">132. Palindrome Partitioning II</a>
63+
<a href="leetcode-132-Palindrome-PartitioningII.html">132. Palindrome Partitioning II</a>
64+
65+
<a href="leetcode-133-Clone-Graph.html">133. Clone Graph</a>

leetcode-133-Clone-Graph.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# 题目描述(中等难度)
2+
3+
![](https://windliang.oss-cn-beijing.aliyuncs.com/133.jpg)
4+
5+
复制一个图,图的节点定义如下。
6+
7+
```java
8+
class Node {
9+
public int val;
10+
public List<Node> neighbors;
11+
12+
public Node() {}
13+
14+
public Node(int _val,List<Node> _neighbors) {
15+
val = _val;
16+
neighbors = _neighbors;
17+
}
18+
};
19+
```
20+
21+
`neighbors` 是一个装 `Node``list` ,因为对象的话,`java` 变量都存储的是引用,所以复制的话要新 `new` 一个 `Node` 放到 `neighbors`
22+
23+
# 思路分析
24+
25+
这个题其实就是对图进行一个遍历,通过 `BFS` 或者 `DFS`。需要解决的问题就是怎么添加当前节点的 `neighbors`,因为遍历当前节点的时候,它的邻居节点可能还没有生成。
26+
27+
# 解法一 BFS
28+
29+
先来一个简单粗暴的想法。
30+
31+
首先对图进行一个 `BFS`,把所有节点 `new` 出来,不处理 `neighbors` ,并且把所有的节点存到 `map` 中。
32+
33+
然后再对图做一个 `BFS`,因为此时所有的节点已经创建了,只需要更新所有节点的 `neighbors`
34+
35+
```java
36+
public Node cloneGraph(Node node) {
37+
if (node == null) {
38+
return node;
39+
}
40+
//第一次 BFS
41+
Queue<Node> queue = new LinkedList<>();
42+
Map<Integer, Node> map = new HashMap<>();
43+
Set<Integer> visited = new HashSet<>();
44+
queue.offer(node);
45+
visited.add(node.val);
46+
while (!queue.isEmpty()) {
47+
Node cur = queue.poll();
48+
//生成每一个节点
49+
Node n = new Node();
50+
n.val = cur.val;
51+
n.neighbors = new ArrayList<Node>();
52+
map.put(n.val, n);
53+
for (Node temp : cur.neighbors) {
54+
if (visited.contains(temp.val)) {
55+
continue;
56+
}
57+
queue.offer(temp);
58+
visited.add(temp.val);
59+
}
60+
}
61+
62+
//第二次 BFS 更新所有节点的 neightbors
63+
queue = new LinkedList<>();
64+
queue.offer(node);
65+
visited = new HashSet<>();
66+
visited.add(node.val);
67+
while (!queue.isEmpty()) {
68+
Node cur = queue.poll();
69+
for (Node temp : cur.neighbors) {
70+
map.get(cur.val).neighbors.add(map.get(temp.val));
71+
}
72+
for (Node temp : cur.neighbors) {
73+
if (visited.contains(temp.val)) {
74+
continue;
75+
}
76+
queue.offer(temp);
77+
visited.add(temp.val);
78+
}
79+
}
80+
return map.get(node.val);
81+
}
82+
83+
```
84+
85+
当然再仔细思考一下,其实我们不需要两次 `BFS`
86+
87+
我们要解决的问题是遍历当前节点的时候,邻居节点没有生成,那么我们可以一边遍历一边生成邻居节点,就可以同时更新 `neighbors `了。
88+
89+
同样需要一个 `map` 记录已经生成的节点。
90+
91+
```java
92+
public Node cloneGraph(Node node) {
93+
if (node == null) {
94+
return node;
95+
}
96+
Queue<Node> queue = new LinkedList<>();
97+
Map<Integer, Node> map = new HashMap<>();
98+
queue.offer(node);
99+
//先生成第一个节点
100+
Node n = new Node();
101+
n.val = node.val;
102+
n.neighbors = new ArrayList<Node>();
103+
map.put(n.val, n);
104+
while (!queue.isEmpty()) {
105+
Node cur = queue.poll();
106+
for (Node temp : cur.neighbors) {
107+
//没有生成的节点就生成
108+
if (!map.containsKey(temp.val)) {
109+
n = new Node();
110+
n.val = temp.val;
111+
n.neighbors = new ArrayList<Node>();
112+
map.put(n.val, n);
113+
queue.offer(temp);
114+
}
115+
map.get(cur.val).neighbors.add(map.get(temp.val));
116+
}
117+
}
118+
119+
return map.get(node.val);
120+
}
121+
```
122+
123+
# 解法二 DFS
124+
125+
`DFS` 的话用递归即可,也用一个 `map` 记录已经生成的节点。
126+
127+
```java
128+
public Node cloneGraph(Node node) {
129+
if (node == null) {
130+
return node;
131+
}
132+
Map<Integer, Node> map = new HashMap<>();
133+
return cloneGrapthHelper(node, map);
134+
}
135+
136+
private Node cloneGrapthHelper(Node node, Map<Integer, Node> map) {
137+
if (map.containsKey(node.val)) {
138+
return map.get(node.val);
139+
}
140+
//生成当前节点
141+
Node n = new Node();
142+
n.val = node.val;
143+
n.neighbors = new ArrayList<Node>();
144+
map.put(node.val, n);
145+
//添加它的所有邻居节点
146+
for (Node temp : node.neighbors) {
147+
n.neighbors.add(cloneGrapthHelper(temp, map));
148+
}
149+
return n;
150+
}
151+
```
152+
153+
#
154+
155+
这道题本质上就是对图的遍历,只要想到用 `map` 去存储已经生成的节点,题目基本上就解决了。

0 commit comments

Comments
 (0)