Published
- 2 min read
Lowest Common Ancestor of a Binary Tree
Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
- Its a binary tree (a tree having atmost 2 children)
- A node can be descendant of itself so the node is included to be an ancestor node, example b/w nodes of differet levels the higher level node can be common for both nodes
- We need to keep track of the parent of each node as we move in the tree
- For simplicity we choose stack as we need to move left and right both at the same time
- move in left subtree first and then in right subtree
- pick a map and keep adding current node parent to it(only till we find the target nodes while traversal)
- keep a set and add target1 path to it
- check which first node from path traversal of target2 is included in node1 path
private Node lowestCommonAncestorInATree(Node root, Node target1, Node target2) {
//we need to keep storing all the ancestors for the node somewhere
//how we should decide which one is lower (map raversal would tell this) ? and each node is the descendant of itself
//how to find common descendant of both given nodes? (set would tell it)
//think about corner cases, both nodes should be given , if one of them is root answer is root
//why we need stack ???? because to move in the nodes, we can use recursion also
Stack<Node> stack = new Stack<>();
map.put(root, null);
//map stores parent of each node
while (!map.containsKey(target1) || !map.containsKey(target2)) {
Node node = stack.pop();
if(node.left != null) {
map.put(node.left, node);
stack.push(node.left);
}
if(node.right != null) {
map.put(node.right, node);
stack.push(node.right);
}
}
HashSet<Node> set = new HashSet<>();
//target will be null when we will reach the parent/root node
while (target1 != null) {
set.add(target1);
target1 = map.get(target1); //here the parent keep changing
}
while (!set.contains(target2)) {
//no need to add the data to the set now
target2 = map.get(target2);
}
return target2;
}