I am doing some JavaScript coding practice, and I wanna copy the Graph
/**
* // Definition for a Node.
* function Node(val, neighbors) {
* this.val = val === undefined ? 0 : val;
* this.neighbors = neighbors === undefined ? [] : neighbors;
* };
*/
/**
* @param {Node} node
* @return {Node}
*/
var cloneGraph = function(node) {
visited = {};
return recursion(node);
function recursion(node){
if (!node) return null;
if (visited[node.val]) return visited[node.val];
// clone node and clone edge
// **I forgot the let, var, const variable declaration here**
root = new Node(node.val);
visited[root.val] = root;
if (!node.neighbors) return root;
for (let i = 0; i < node.neighbors.length; i++) {
root.neighbors.push(recursion(node.neighbors[i]));
}
return root;
}
};
Here is my code. I forgot to add the variable declaration const
, let
, var
when initialize the new Node. However, seems like the reference is not correct here.
Error : You must return the copy of the given node as a reference to the cloned graph.
.
Can any one help me understand, why const the var declaration matters here ? For this coding, var
, let
, const
can pass, however, var
says to be global, const
and let
seems like to be block level right ? Thanks.
However, when use d
and c
blow, we can get the same output as object.
d = new Node(node.val)
console.log(d)
const c = new Node(node.val)
console.log(c)
Because root
has been declare as global variable and be changed in every recursive loop, in this line:
root.neighbors.push(recursion(node.neighbors[i]));
root
will not be the current node that in current loop, but the last reference it has been assigned to.
Let demonstrate it by an simple graph:
const oldGraph = [{
val: 1,
neighbors: [{
val: 2
}, {
val: 3
}]
}];
So run cloneGraph(oldGraph[0])
, after value 2 done return after check !node.neighbors
, recursion back to the line root.neighbors.push(recursion(node.neighbors[i]));
. Now root
is the node 2 because it has been assigned to new node val 2 in the second recursion, not the root as node 1 you expected.
The variable declaration with var
, let
, const
helps in this case, because they keep the root
scope inside current recursion, each iteration will create a new root, not changed any other references.
Test here:
function Node(node) {
this.val = node.val;
this.neighbors = [];
}
var cloneGraph = function(node) {
visited = {};
return recursion(node);
function recursion(node){
if (!node) return null;
if (visited[node.val]) return visited[node.val];
// clone node and clone edge
// **I forgot the let, var, const variable declaration here**
let root = new Node(node);
visited[root.val] = root;
if (!node.neighbors) return root;
for (let i = 0; i < node.neighbors.length; i++) {
root.neighbors.push(recursion(node.neighbors[i]));
}
return root;
}
};
oldGraph = [{
val: 1,
neighbors: [{
val: 2
}, {
val: 3
}]
}];
console.log(cloneGraph(oldGraph[0]));