【试题描述】

求二叉树中任意两个节点的最近公共祖先也称为LCA问题(Lowest Common Ancestor)。

二叉查找树

如果该二叉树是二叉查找树,那么求解LCA十分简单。

基本思想为:从树根开始,该节点的值为t,如果t大于t1和t2,说明t1和t2都位于t的左侧,所以它们的共同祖先必定在t的左子树中,从t.left开始搜索;如果t小于t1和t2,说明t1和t2都位于t的右侧,那么从t.right开始搜索;如果t1<t< t2,说明t1和t2位于t的两侧,那么该节点t为公共祖先。

如果t1是t2的祖先,那么应该返回t1的父节点;同理,如果t2是t1的祖先,应该返回t2的父节点。

【参考代码】

 1 public int query(Node t1, Node t2, Node t) {
 2     int left = t1.value;
 3     int right = t2.value;
 4     Node parent = null;
 5
 6     if (left > right) {
 7         int temp = left;
 8         left = right;
 9         right = temp;
10     }
11
12     while (true) {
13         if (t.value < left) {
14             parent = t;
15             t = t.right;
16         } else if (t.value > right) {
17             parent = t;
18             t = t.left;
19         } else if (t.value == left || t.value == right) {
20             return parent.value;
21         } else {
22             return t.value;
23         }
24     }
25 }

普通二叉树

算法思想:如果一个节点的左子树包含p,q中的一个节点,右子树包含另一个,则这个节点就是p,q的最近公共祖先

【参考代码】

解法一:

 1 public static Node findNCA(Node root, Node p, Node q)
 2     {
 3         if (isintree(root.left, p) && isintree(root.left, q))
 4             return findNCA(root.left, p, q);
 5         if (isintree(root.right, p) && isintree(root.right, q))
 6             return findNCA(root.right, p, q);
 7         return root;
 8     }
 9
10     public static boolean isintree(Node root, Node node)
11     {
12         if (root == null)
13             return false;
14         if (root == node)
15             return true;
16         return isintree(root.left, node) || isintree(root.right, node);
17     }

解法二:

 1 static int TWO_NODES_FOUND = 2;
 2     static int ONE_NODES_FOUND = 1;
 3     static int NO_NODES_FOUND = 0;
 4
 5     public static int covers(Node root, Node p, Node q)
 6     {
 7         int ret = NO_NODES_FOUND;
 8         if (root == null)
 9             return ret;
10         if (root == p || root == q)
11             ret += 1;
12         ret += covers(root.left, p, q);
13         if (ret == TWO_NODES_FOUND)
14             return ret;
15         return ret + covers(root.right, p, q);
16     }
17
18     private static Node findNCA(Node root, Node p, Node q)
19     {
20         if (q == p && (root.left == q || root.right == q))
21             return root;
22         int nodesFromLeft = covers(root.left, p, q);
23         if (nodesFromLeft == TWO_NODES_FOUND)
24         {
25             if (root.left == p || root.left == q)
26                 return root.left;
27             else
28                 return findNCA(root.left, p, q);
29         } else if (nodesFromLeft == ONE_NODES_FOUND)
30         {
31             if (root == p)
32                 return p;
33             else if (root == q)
34                 return q;
35         }
36
37         int nodesFromRight = covers(root.right, p, q);
38         if (nodesFromRight == TWO_NODES_FOUND)
39         {
40             if (root.right == p || root.right == q)
41                 return root.right;
42             else
43                 return findNCA(root.right, p, q);
44         } else if (nodesFromRight == ONE_NODES_FOUND)
45         {
46             if (root == p)
47                 return p;
48             else if (root == q)
49                 return q;
50         }
51
52         if (nodesFromLeft == ONE_NODES_FOUND
53                 && nodesFromLeft == ONE_NODES_FOUND)
54             return root;
55         else
56             return null;
57     }

解法三:
网上版本:

 1 public static int FindNCA(Node root, Node a, Node b, Node out)
 2     {
 3         if (root == null)
 4             return 0;
 5         if (root == a || root == b)
 6             return 1;
 7
 8         int iLeft = FindNCA(root.left, a, b, out);
 9         if (iLeft == 2)
10             return 2;
11
12         int iRight = FindNCA(root.right, a, b, out);
13         if (iRight == 2)
14             return 2;
15
16         if (iLeft + iRight == 2)
17             out = root;
18
19         return iLeft + iRight;
20     }

这个网上说输出时 当为2时才输出,但是为2时,不能判断如果其中一个是另一个的父亲节点情况。所以理论上应该改为当返回结果
大于0时,就可以输出结果。但是不太确定正确性,应该程序是正确的。

参考:

http://blog.csdn.net/w397090770/article/details/7615447

【IT笔试面试题整理】寻找二叉树两节点的最近的公共祖先相关推荐

  1. 寻找树中两个结点的最低公共祖先

    寻找树中两个结点的最低公共祖先 Q:在树中寻找两个结点的最低公共祖先,是什么意思呢? A:树是由根节点衍生左右孩子继续衍生左右孩子的左右孩子.所以呢树中的两个结点是一定拥有最低公共祖先(这两个结点Q: ...

  2. 数据结构-寻找二叉树两节点的最近公共祖先(Java)

    寻找最近公共祖先 题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个节点 p.q,最近公共祖先表示为一个节点 x,满足 ...

  3. 求二叉树两个结点的最近公共祖先

    题目描述: 一颗二叉树按顺序存储结构进行存储,设计一个算法,求编号i和j的最近公共祖先 思路: 已知:二叉树.顺序存储 空的结点用"#"表示 如果i,j所在位置的结点数据不是&qu ...

  4. 【IT笔试面试题整理】 二叉树任意两个节点间最大距离

    求一个二叉树中任意两个节点间的最大距离,两个节点的距离的定义是这两个节点间边的个数, 比如某个孩子节点和父节点间的距离是1,和相邻兄弟节点间的距离是2,优化时间空间复杂度. 一种是:经过根节点,此时只 ...

  5. 【IT笔试面试题整理】二叉树中和为某一值的路径--从根到叶子节点

    [试题描述] 输入一个整数和一棵二元树.从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条 路径.打印出和与输入整数相等的所有路径. 例如输入整数 22 和如下二元树             ...

  6. 【IT笔试面试题整理】二叉树中和为某一值的路径--所有可能路径

    [试题描述] You are given a binary tree in which each node contains a value. Design an algorithm to print ...

  7. 寻找二叉树中两个结点的最近公共祖先

    寻找二叉树中两个结点的最近公共祖先(这两个结点一定在树中) 对于二叉树中两个结点的最近公共祖先来说 ,这两个结点分别在自己的左子树和右子树中,所以要寻找二叉树中两个结点的最近公共祖先可以: 从根结点开 ...

  8. 寻找二叉树两个结点的最低共同父节点

    寻找二叉树两个结点的最低共同父节点 题目:二叉树的结点的定义如下: struct TreeNode {int m_nValue;TreeNode *m_pLeft;TreeNode *m_pRight ...

  9. 树中两个结点的最低公共祖先

    题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数 ...

最新文章

  1. windows 远程登录用户管理
  2. 让Windows 2000/XP系统自动登陆
  3. 12306”的架构到底有多牛逼?
  4. html间隔怎么打_iPhone手机便签内容怎么设为重要事项?
  5. 五大最主流浏览器综合性能测试
  6. 《程序员修炼之道》读后感02
  7. Android View添加 Listener 小技巧示例
  8. qt 在qtextedit显示数组_QtWidget: 设置QTextEdit的各种颜色
  9. Node.js CVE-2017-14849复现(详细步骤)
  10. 僵化封闭是世界的新主流?
  11. 【CF1312D】Count the Arrays(计数)
  12. CSS实例——远视图
  13. ESP32 WS2812B灯带 代码
  14. 公司合同管理软件有哪些?
  15. python堆叠柱状图加数字_Python 堆叠柱状图绘制方法
  16. HDU 3533 简单bfs 主要是MLE问题
  17. 直观理解深度学习中的反卷积、导向反向传播
  18. U8-固定资产月末结账报错:BOF或EOF中有一个是真
  19. STM32——用固件库实现流水灯(源码+仿真图)
  20. Cubase10自编曲平台,享受音乐带来的快乐!

热门文章

  1. Servlet调用流程
  2. 夏普出了款机器人手机 可以和你“坐着聊聊天”
  3. TFBOYS饭票上线引热议,骗局之外,区块链技术能重构娱乐产业吗?
  4. 基于vue2 + vue-router + vuex 构建的一个新闻类大型单页面应用 —— 今日头条
  5. P1244 青蛙过河
  6. hadoop datanode启动失败
  7. Lower Power with CPF(三)
  8. 命令行实现更强大的php交互
  9. 几个常用shell脚本命令
  10. [WPF]获取控件间的相对位置