The problem:

Given node P and node Q in a binary tree T.

Find out the lowest common ancestor of the two nodes.

Analysis:

The answer of this problem could only be the following two cases:

case 1: P or Q itself is the lowest common ancestor.

P

.........

X  Q

case 2: P and Q are in the different sub-trees of a node.

A

..........

P    Q

Additional Condition:

1. If the nodes in the tree has the parent pointer.

solution 1:  Starting from node P and Q, traverse along the parent link back to the root, compute the distance of P to root and Q to root respectively.

Compute the difference d of those two distances. Move the node with longer distance d nodes along parent link. Then begin move P and Q one node each time back to root, and check the nodes of P and Q point to, if the nodes are the same node, return the node.

private TreeNode find_CLA(TreeNode root, TreeNode p, TreeNode q) {
if (root == null)
return null;
if (p == null && q != null)
return q;
if (p != null && q == null)
return p;
int dist_p, dist_q, dist_diff;
TreeNode temp;
temp = p;
while (temp != root) {
temp = temp.parent;
dist_p++;
}
temp = q;
while (temp != root) {
temp = temp.parent;
dist_q++;
}
if (dist_p > dist_q) {
dist_diff = dist_p - dist_q;
temp = p;
}else {
dist_diff = dist_q - dist_p;
temp = q;
}
while (dist_diff > 0) {
temp = temp.parent;
dist_diff--;
}
while (p != root) {
if (p == q)
return p;
p = p.parent;
q = p.parent;
}
return root;
}

Solution 2. Use a Hashset.

The basic idea underlying this method is to use a hashset to record all nodes from P to root. then starting fom q to root, we check each node along this path. if the node appear in the hashset, then the node is the lowest common ancestor.

private TreeNode find_LCA(TreeNode root, TreeNode p, TreeNode q) {
if (root == null)
return null;
if (p == null || q != null)
return q;
if (p != null || q == null)
return p;
Set<TreeNode> hashset = new HashSet<TreeNode> ();
while (p != root) {
hashset.add(p);
p = p.parent;
}
while (q != root) {
if (hashset.contains(p)){
return p;
}
}
return root;
}

What if we don't have parent pointer?

The problem gets complicated because we need to search all possible branches. But the idea behind it is also very elegant : use recursion!!!

The basic idea:

Since the problem is to find the lowest common ancestor, at each node, we would not be able to know its children in just one time traversaL.

Thus we choose to search through bottom-up way. Bottom-up way could be easily achieved through post-order traversal.

The invariant in recursion: (at each node)

Key idea: Once we encouter p or q, we return its pointer. Only LCA could be possible to have two sub-child-functions (not null).

1. We check if the current node is P or Q.  Iff true, we return current node, and stop searching along this branch.

2. If the current node is neither P or Q.  We check it's two sub-child-functions.

2.1 Iff two sub-children-functions's return value is not null, then the current node must be the LCA, we return it directly.

2.2 Iff only one branch's return value is not null,  return pass the branch's return value into the current node's pre level.

Note: The return value could be the LCA or just p or q's reference.

2.3. Iff both branch's return value is null, pass the null into pre level.

Key : the null pointer here is very important, it helps to indicate whether a branch contains target node or any node in {P, Q}

private TreeNode find_LCA(TreeNode root, TreeNode p, TreeNode q) {
if (root == null)
return null;
if (root == p || root == q)
return root;
TreeNode left = find_LCA(root.left, p, q);
TreeNode right = find_LCA(root.right, p, q);
if (left && right)
return root;
return left ? left : right;
}

Lowest Common Ancestor in Binary Tree的更多相关文章

  1. 48. 二叉树两结点的最低共同父结点(3种变种情况)[Get lowest common ancestor of binary tree]

    [题目] 输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点. 二叉树的结点定义如下:  C++ Code  123456   struct BinaryTreeNode {     int ...

  2. [LeetCode] 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 ...

  3. [LeetCode] Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最小共同父节点

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  4. [LeetCode]Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  5. 数据结构与算法(1)支线任务4——Lowest Common Ancestor of a Binary Tree

    题目如下:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/ Given a binary tree, fin ...

  6. Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  7. 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 ...

  8. leetcode 235. Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  9. leetcode 236. 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 ...

随机推荐

  1. spring servlet 扩展undertow

    官方地址:http://undertow.io/documentation/servlet/servlet-extensions.html  留待学习中,mark一下 源码地址:https://git ...

  2. Android微信智能心跳方案

    前言:在13年11月中旬时,因为基础组件组人手紧张,Leo安排我和春哥去广州轮岗支援.刚到广州的时候,Ray让我和春哥对Line和WhatsApp的心跳机制进行分析.我和春哥抓包测试了差不多两个多礼拜 ...

  3. CentOS 6.7增加SWAP交换分区

    任务:新增一个1GB的SWAP分区,并开机自动挂载 1.在/var目录下新增SWAPFILE交换区文件 2.生成SWAP分区 mkswap /var/SWAPFILE 3.激活SWAP分区 swapo ...

  4. Linux系统下Memcached的安装以及自启动

    一.准备工作: 1.下载libevent:http://monkey.org/~provos/libevent/ (由于memcached与客户端的通信是借助libevent来实现的,所以此动作必须在 ...

  5. WCF 生产json对外的接口

    调用wcf public ActionResult Index() { ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序."; WC ...

  6. C#内存修改

    先通过 System.Diagnostics.Process类获取想要编辑的进程 调用API [Flags]                    public enum ProcessAccessT ...

  7. CentOS 7设置iptables防火墙开放proftpd端口

    由于ftp的被动模式是这样的,客户端跟服务器端的21号端口交互信令,服务器端开启21号端口能够使客户端登录以及查看目录.但是ftp被动模式用于传输数据的端口却不是21,而是大于1024的随机或配置文件 ...

  8. CI 笔记2,(命令规范等)

    调试模式开启,$this->output->enable_profiler(TRUE); 保留字,不能和控制器重名,有3个,CI_Controller ,Default, index.这三 ...

  9. 玩转CSLA.NET小技巧系列一:跳转页面丢失session,如何解决

    很少写代码,最近在写代码被登录难倒了,这丫的一直在跟我较劲 每次登录完跳转到首页后还是未登录状态 if (ModelState.IsValid) { bool isSuccess = FI.Finan ...

  10. 数字证书文件cer和pfx的区别

    作为文件形式存在的证书一般有这几种格式: 1.带有私钥的证书 由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形 ...