-
Notifications
You must be signed in to change notification settings - Fork 43
/
CloneGraph.java
206 lines (179 loc) · 6.44 KB
/
CloneGraph.java
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package LeetCodeJava.Graph;
import LeetCodeJava.DataStructure.Node;
import java.util.*;
// https://leetcode.com/problems/clone-graph/
// NOTE !!! : Node.val is unique for each node.
/**
* Constraints:
*
* - The number of nodes in the graph is in the range [0, 100].
* - 1 <= Node.val <= 100
* - Node.val is unique for each node.
* - There are no repeated edges and no self-loops in the graph.
* - The Graph is connected and all nodes can be visited starting from the given node.
*/
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> neighbors;
public Node() {
val = 0;
neighbors = new ArrayList<Node>();
}
public Node(int _val) {
val = _val;
neighbors = new ArrayList<Node>();
}
public Node(int _val, ArrayList<Node> _neighbors) {
val = _val;
neighbors = _neighbors;
}
}
*/
public class CloneGraph {
// V0
// IDEA : DFS
public Node cloneGraph(Node node) {
// init hashmap
// NOTE : hashmap form : <Integer, Node>
HashMap<Integer, Node> _visited = new HashMap<>();
return _clone(_visited, node);
}
private Node _clone(HashMap<Integer, Node> visited, Node node){
// NOTE !!! handle edge case, if node is null, return itself directly
if (node == null) {
return node;
}
int cur_val = node.val;
// case 1) already visited, then return hashmap 's value (Node type) directly
if (visited.containsKey(cur_val)){
return visited.get(cur_val);
}
// NOTE !!! we init copied node as below
Node copiedNode = new Node(node.val, new ArrayList());
visited.put(cur_val, copiedNode);
// case 2) node is NOT visited yet, we go through all its neighbors,
for (Node _node : node.neighbors){
// NOTE !!! op here : we add new copied node to copiedNode.neighbors,
// (e.g. : copiedNode.neighbors.add)
// instead of return it directly
copiedNode.neighbors.add(_clone(visited, _node));
}
// NOTE !!! we return copiedNode as final step in code
// -> once code reach here, means all after all recursive call are completed
// -> copiedNode should have all collected nodes
return copiedNode;
}
// V0'
// Node clonedNode = new Node();
// public Node cloneGraph(Node node) {
//
// if (node == null){
// return node;
// }
//
// // build map : {node_val : node_neighbors}
// Map<Integer, Set<Node>> map = new HashMap<>();
// for (Node x : node.neighbors){
// int _val = x.val;
// List<Node> _neighbors = x.neighbors;
// if (!map.containsKey(_val)){
// map.put(_val, new HashSet<>());
// }
// for (Node y : _neighbors){
// map.get(_val).add(y);
// }
// }
//
// List<Integer> visited = new ArrayList<>();
// // (status) 0 : not visited, 1 : visiting, 2 : visited
// int status = 0;
// _help(node, visited, map, status);
// return this.clonedNode;
// }
//
// private void _help(Node node, List<Integer> visited, Map<Integer, Set<Node>> map, int status){
//
// // all nodes are visited
// if (visited.size() == map.keySet().size()){
// return;
// }
//
// if (!visited.contains(node)){
// this.clonedNode = node;
// visited.add(node.val);
// if (map.get(node).isEmpty()){
// status = 2;
// map.remove(node.val);
// }
// }
//
// for (Node _node : map.get(node)){
// // remove visiting node in map val
// map.get(_node.val).remove(_node);
// _help(_node, visited, map, 1);
// }
//
// }
// V1
// IDEA : DFS
// https://leetcode.com/problems/clone-graph/editorial/
private HashMap <Node, Node> visited = new HashMap <> ();
public Node cloneGraph_1(Node node) {
if (node == null) {
return node;
}
// If the node was already visited before.
// Return the clone from the visited dictionary.
if (visited.containsKey(node)) {
return visited.get(node);
}
// Create a clone for the given node.
// Note that we don't have cloned neighbors as of now, hence [].
Node cloneNode = new Node(node.val, new ArrayList());
// The key is original node and value being the clone node.
visited.put(node, cloneNode);
// Iterate through the neighbors to generate their clones
// and prepare a list of cloned neighbors to be added to the cloned node.
for (Node neighbor: node.neighbors) {
cloneNode.neighbors.add(cloneGraph_1(neighbor));
}
// NOTE !!! after dfs, we return final result
return cloneNode;
}
// V2
// IDEA : BFS
// https://leetcode.com/problems/clone-graph/editorial/
public Node cloneGraph_2(Node node) {
if (node == null) {
return node;
}
// Hash map to save the visited node and it's respective clone
// as key and value respectively. This helps to avoid cycles.
HashMap<Node, Node> visited = new HashMap();
// Put the first node in the queue
LinkedList<Node> queue = new LinkedList<Node> ();
queue.add(node);
// Clone the node and put it in the visited dictionary.
visited.put(node, new Node(node.val, new ArrayList()));
// Start BFS traversal
while (!queue.isEmpty()) {
// Pop a node say "n" from the front of the queue.
Node n = queue.remove();
// Iterate through all the neighbors of the node "n"
for (Node neighbor: n.neighbors) {
if (!visited.containsKey(neighbor)) {
// Clone the neighbor and put in the visited, if not present already
visited.put(neighbor, new Node(neighbor.val, new ArrayList()));
// Add the newly encountered node to the queue.
queue.add(neighbor);
}
// Add the clone of the neighbor to the neighbors of the clone node "n".
visited.get(n).neighbors.add(visited.get(neighbor));
}
}
// Return the clone of the node from visited.
return visited.get(node);
}
}