【IT笔试面试题整理】寻找二叉树两节点的最近的公共祖先
【试题描述】
求二叉树中任意两个节点的最近公共祖先也称为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笔试面试题整理】寻找二叉树两节点的最近的公共祖先的更多相关文章
- 【剑指Offer学习】【面试题50:树中两个结点的最低公共祖先】
题目:求树中两个结点的最低公共祖先,此树不是二叉树,而且没有指向父节点的指针. 树的结点定义 private static class TreeNode { int val; List<Tree ...
- (剑指Offer)面试题50:树中两个结点的最低公共祖先
题目: 求树中两个结点的最低公共祖先 思路: 考虑一下几种情况: 1.该树为二叉搜索树 二叉搜索树是排序树,位于左子树点的结点都比父结点小,而位于右子树的结点都比父结点大,只需要从树的根结点开始和两个 ...
- 【IT笔试面试题整理】二叉树中和为某一值的路径--所有可能路径
[试题描述] You are given a binary tree in which each node contains a value. Design an algorithm to print ...
- 《剑指offer》第六十八题(树中两个结点的最低公共祖先)
// 面试题68:树中两个结点的最低公共祖先 // 题目:输入两个树结点,求它们的最低公共祖先. #include <iostream> #include "Tree.h&quo ...
- Java笔试面试题整理第一波
转载至:http://blog.csdn.net/shakespeare001/article/details/51151650 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第八波
转载至:http://blog.csdn.net/shakespeare001/article/details/51388516 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第六波(修正版)
转载至:http://blog.csdn.net/shakespeare001/article/details/51330745 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第五波
转载至:http://blog.csdn.net/shakespeare001/article/details/51321498 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第四波
转载至:http://blog.csdn.net/shakespeare001/article/details/51274685 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
随机推荐
- 《it项目管理那些事》学习笔记
此书适合:计算及相关专业的学生,想成为测试工程师.软件工程师.进入项目经理的人,或者经验丰富的it经理人. 之所以称为学习笔记,是加上我从百度搜到一些在看书过程中不明白的it语,作为菜鸟的我,得多看看 ...
- URL中文编码
/// <summary> /// GB2312编码 /// </summary> /// <param name=" ...
- AngularJS 杂项知识点
1.要用ngChange要同时使用ngModel,下拉选择获取当前选中值. 2.打包代替动态加载(js文件) requirejs真正的价值在于模块化,不是动态加载,angularjs本身有模块化机制, ...
- ASP.NET Web API 框架研究 核心的消息处理管道
ASP.NET Web API 的核心框架是一个由一组HttpMessageHandler有序组成的双工消息处理管道:寄宿监听到请求接受后,把消息传入该管道经过所有HttpMessageHandler ...
- unigui作中间件使用
unigui作中间件使用 可返回string或者tstream数据. 如果返回JSON字符,则UNIGUI就是REST 中间件. procedure TUniServerModule.UniGUISe ...
- https://www.cnblogs.com/hnxxcxg/p/6085149.html
DELPHI微信支付代码 不管是微信支付还是支付宝支付, 3个最棘手的问题是:1,如何生成签名2,支付请求如何提交3, 如何验证签名 下面就围绕这二个问题来讲. 我使用的是XE3. 先看微信支付: ...
- Android-Java-synchronized静态方法&字节码文件对象
上一篇博客 Android-Java-同步方法-synchronized,中讲解了普通方法加入synchronized修饰符,此synchronized的同步锁是this,还介绍方法的封装性,这篇博客 ...
- SQL关闭自增长列标识:SET IDENTITY_INSERT
关闭自增长列添加记录,然后再恢复自增长功能 SET IDENTITY_INSERT 表名 ON; inert ,); SET IDENTITY_INSERT 表名 OFF
- K8s之spinnaker
一.spinnaker概述 1.spinnaker是netflix开源的一款云发布CI/CD,其前身是Asgard,spinnaker支持各种部署目标,包括OpenStack.DC/OS.Kubern ...
- nginx在Linux下的安装
安装之前的环境装备: 1.ngiinx 是C 语言开发的,我们上传的文件还是源码,需要gcc环境编译源码 : yum install gcc-c++ 2.nginx的http模块使用pcre来解析正则 ...