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. vi模式

    保存命令 按ESC键 跳到命令模式,然后: :w 保存文件但不退出vi:w file 将修改另外保存到file中,不退出vi:w! 强制保存,不推出vi:wq 保存文件并退出vi:wq! 强制保存文件 ...

  2. error: device not found - waiting for device -

    执行 cocos run -p android 时报的这个错误 连接上 android 手机, 手机开启开发者模式.  设置--其他高级设置--开发者选项--USB 调试

  3. svn 设置钩子将代码同步到web目录下面

    首先:确定思路: 要在SVN服务中,找到仓库文件夹的位置,在相应的项目中找到hooks文件夹.在该文件中添加一个post-commit文件: 当有commit动作发生时(提交到SVN服务是就会执行这个 ...

  4. 11月15日jquery学习笔记

    1.属性 jQuery对象是类数组,拥有length属性和介于0~length-1之间的数值属性,可以用toArray()方法将jQuery对象转化为真实数组. selector属性是创建jQuery ...

  5. instanceof的用法①

    public class typeof1{ private String a="zzw"; public void instance(){ if(a instanceof Stri ...

  6. HTML5 FileReader读取Blob对象API详解

    使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要读取的文件或数据.其中File对象可以是来自用 ...

  7. CouchBase 遇到问题笔记(一)

    刚开始看CouchBase,按照官网给出的示例,边敲边理解,遇到了一个很奇怪的问题,如下代码: IView<IViewRow> view = client.GetView("be ...

  8. VB热点答疑(2016.5.11更新Q4、Q5)

    收录助教君在VB习题课上最常被问到的问题,每周更新,希望对大家有所帮助. Q1.如何让新的文本内容接在原来的内容后面/下一行显示? A1.例如,Label1.text原本的内容是"VB程序设 ...

  9. 深入理解ReentrantLock

    在Java中通常实现锁有两种方式,一种是synchronized关键字,另一种是Lock.二者其实并没有什么必然联系,但是各有各的特点,在使用中可以进行取舍的使用.首先我们先对比下两者. 实现: 首先 ...

  10. HDU 3359 Kind of a Blur(高斯消元)

    题意: H * W (W,H <= 10) 的矩阵A的某个元素A[i][j],从它出发到其他点的曼哈顿距离小于等于D的所有值的和S[i][j]除上可达点的数目,构成了矩阵B.给定矩阵B,求矩阵A ...