【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相关的笔试面试知识点,其他几 ...
随机推荐
- Hdu1151 Air Raid(最小覆盖路径)
Air Raid Problem Description Consider a town where all the streets are one-way and each street leads ...
- Cerebro_变量名搜索插件
Cerebro 安装 兼容环境:Windows, MacOS, Linux 插件依赖于 Cerebro,下载地址: https://github.com/KELiON/cerebro/releases ...
- 电容器的ESR
电容器的ESR(等效串联电阻)Equivalent Series Resistance 作为开关电源的输出整流滤波电容器,电容量往往是首要的选择,铝电解电容器的电容量完全可以满足要求,而ESR则 ...
- jQuery WeUI V0.4.2 发布
http://www.oschina.net/news/71590/jquery-weui-v0-4-2 jQuery WeUI V0.4.2 发布了! jQuery WeUI 中使用的是官方WeUI ...
- Linux 下建立 SSH 隧道做 Socket 代理
背景 需要解决本地访问内部集群中各台机器上的内部web服务,但是内部集群不能直接访问,只能通过edge node节点跳转. 前提:edge node可以通过ssh方式访问,在edge node上可以访 ...
- 背水一战 Windows 10 (43) - C# 7.0 新特性
[源码下载] 背水一战 Windows 10 (43) - C# 7.0 新特性 作者:webabcd 介绍背水一战 Windows 10 之 C# 7.0 新特性 介绍 C# 7.0 的新特性 示例 ...
- 基本数据类型补充 set集合 深浅拷贝
一.基本数据类型补充 1,关于int和str在之前的学习中已经介绍了80%以上了,现在再补充一个字符串的基本操作: li = ['李嘉诚','何炅','海峰','刘嘉玲'] s = "_&q ...
- Python大法之告别脚本小子系列—各类URL采集器编写
本文作者:i春秋签约作家——阿甫哥哥 系列文章专辑:https://bbs.ichunqiu.com/forum.php?mod=collection&action=view&ctid ...
- solr初识
参考资料http://blog.csdn.net/l1028386804/article/details/70199983
- DevOps - CI - Sonar
Sonar 官方信息 https://www.sonarqube.org/ https://www.sonarqube.org/downloads/ https://docs.sonarqube.or ...