Here is the question posted on here years ago about an interview question where given a node from a DOM tree, we need to find the node in the same position from an identical DOM tree.
Here is the an iterative solution I came up with
const findCorrespondingNode = (rootA, rootB, nodeA) => {
let currentNode = nodeA;
const path = [];
while (currentNode !== rootA) {
const index = Array.prototype.indexOf.call(
currentNode.parentElement.children,
currentNode
);
path.push(index);
currentNode = currentNode.parentElement;
}
currentNode = rootB;
while (path.length) {
currentNode = currentNode.children[path.pop()];
}
return currentNode;
}
Basically I just walk backwards from the target to root, creating the reverse path. The reverse path is an array where each element is the child index of a node. Travel down the path from rootB to target, popping off the next index until the path array is empty. Finally we return the pointer to the target node.
My question is:
- what is the (average) time complexity for this solution? The worse case is easy since we need to visit each node once so it is going to be
O(n)
,n
being the number of DOM nodes in the DOM tree. I think it happens when we have two linked lists and the target node is the last node in each linked list. The confusion part for me is that for each level we are also callingArray.prototype.indexOf
to get the index, and this might take up toO(D)
, D being the tree's diameter and for a leaf node it is going to takeO((some-constant)n)
to get the index. , More importantly, what is the average time complexity? We are traversing a tree twice. It seems like it is going to be the height or the depth of the tree. If it is a completely balanced tree, the height of the tree is going to belogN
. Does that mean the average time complexity islogN
? - If I write the solution using a recursive DFS approach, where we traverse both trees simultaneously, i.e.
const findCorrespondingNode = (rootA, rootB, target) => {
if(rootA === target) {
return rootB;
}
for (let i = 0; i < rootA.children.length; i++) {
const foundNode = findCorrespondingNode(rootA.children[i], rootB.children[i], target);
if(foundNode) return foundNode;
}
}
What is the time complexity in this case? Still worse case O(n)
and average/best case O(logN)
. Is this recursive approach better than the iterative approach in terms of time complexity since we wouldn't need to do indexOf
for each level?