Lowest/first common ancestor

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;
 }
}




// case 1: no parent pointer
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;
}

// case 2: has parent pointer
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;
 }
}

/*
Third Solution (With Parent) 
两个节点都向上遍历到根,拿到两个深度。对其中较深的一个节点向上遍历到两个节点深度一样。然后两个指针同时向上遍历,一直到指向同一个节点
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值