public interface FirstCommonAncestor {
/**
* Given two nodes of a tree,
* method should return the deepest common ancestor of those nodes.
*
* A
* / \
* B C
* / \ \
* D E M
* / \
* G F
*
* commonAncestor(D, F) = B
* commonAncestor(C, G) = A
*/
public Node commonAncestor (Node nodeOne, Node nodeTwo);
}
class Node {
final Node parent;
final Node left;
final Node right;
public Node (Node parent, Node left, Node right, data) {
this .parent = parent;
this .left = left;
this .right = right;
this .data = data
}
boolean isRoot() {
return parent == null ;
}
}
public Node commonAncestor (Node root, Node p, Node q) {
if (root == null )
return null ;
if (root == p || root == q)
return root;
Node left = commonAncestor(root.left, p, q);
Node right = commonAncestor(root.right, p, q);
if (left != null && right != null ) {
return root;
}
return left != null ? left : right;
}
public class FirstCommonAncestorImpl implements FirstCommonAncestor {
@Override
public Node commonAncestor (Node nodeOne, Node nodeTwo) {
if (nodeOne == null || nodeTwo == null )
return null ;
Set<Node> hs = new HashSet<Node>();
while (!nodeOne.isRoot() || !nodeTwo.isRoot()) {
if (!nodeOne.isRoot()) {
if (hs.contains(nodeOne.parent)) {
return nodeOne.parent;
}
hs.add(nodeOne.parent);
nodeOne = nodeOne.parent;
}
if (!nodeTwo.isRoot()) {
if (hs.contains(nodeTwo.parent)) {
return nodeTwo.parent;
}
hs.add(nodeTwo.parent);
nodeTwo = nodeTwo.parent;
}
}
return null ;
}
}