Hey Rajat, great post! The explanation and the image really helped to understand it.
I solved using your initial solution, but slightly differently:
function getPath(node, rootA) {
const path = [];
let currentNode = node;
while (currentNode !== rootA) {
const parent = currentNode.parentElement;
const index = [...parent.children].indexOf(currentNode);
path.unshift(index);
currentNode = parent;
}
return path;
}
function getNodeFromPath(rootB, path) {
return path.reduce((node, index) => node.children[index], rootB);
}
I got the path in the top-down order, that's why I used unshift instead of push, and then I reduced that path until its last item to find the correspondent node from root B.
Now, doing this recursively would be:
function findNode(nodeA, nodeB, targetNode) {
for (let index = 0; index < nodeA.childElementCount; index++) {
const currentNode = nodeA.children[index];
if (currentNode === targetNode) {
return nodeB.children[index];
}
if (currentNode.childElementCount) {
return findNode(currentNode, nodeB.children[index], targetNode);
}
}
}
The idea is to go from the top until finding the node from root A. Once that is done, return the node from root B at the same position, otherwise, loop its children (if any) using the same function (recursively).
The recursive solution is probably more performant because:
I'm not sure how to express that complexity in terms of the Big O notation, my guess is that the recursive solution is O(n) where n is the length of root A's tree. Maybe the interactive solution would be expressed in the same way, although we are looping it twice. Any ideas?