总结所有有关二叉树公共祖先问题
Posted 满眼*星辰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了总结所有有关二叉树公共祖先问题相关的知识,希望对你有一定的参考价值。
满二叉树最近公共祖先
将一棵无穷大满二叉树的结点按根结点一层一层地从左往右编号,根结点编号为1。现给定a,b为两个结点。设计一个算法,返回a、b最近的公共祖先的编号。注意其祖先也可能是结点本身。
测试样例:
2,3
返回:1
链接:https://www.nowcoder.com/questionTerminal/70e00e490b454006976c1fdf47f155d9
来源:牛客网
思路
因为是按照0,1,2,3这样的满二叉树,所以可以直接用公式找到其父亲节点
父亲节点 = 孩子节点 / 2
找到最低层的那个节点,然后向上找两个节点的父节点,判断两者父亲节点是否相同
代码
import java.util.*;
public class LCA {
public int getLCA(int a, int b) {
if(a > b) {
int tmp = a;
a = b;
b = tmp;
}
if(a == b) return a;
//b最大了
while(a != b) {
b = b/2;
if(b < a) {
a = a/2;
if(a == b) break;
}
}
return a;
}
}
二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x
的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 输出: 6 解释: 节点 2
和节点 8 的最近公共祖先是 6。 示例 2:输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 输出: 2 解释: 节点 2
和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。说明:
所有节点的值都是唯一的。 p、q 为不同节点且均存在于给定的二叉搜索树中。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof
思路
若 root.val < p.val,则 p 在 root 右子树 中;
若 root.val > p.val,则 p 在 root 左子树 中;
若 root.val = p.val ,则 p 和 root 指向 同一节点 。
代码-遍历
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while(true) {
if(root.val > p.val && root.val > q.val) {
root = root.left;
}else if(root.val < p.val && root.val < q.val) {
root = root.right;
}else break;
}
return root;
}
}
代码-递归
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root.val < p.val && root.val < q.val)
return lowestCommonAncestor(root.right, p, q);
if(root.val > p.val && root.val > q.val)
return lowestCommonAncestor(root.left, p, q);
return root;
}
}
二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x
的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5
和节点 1 的最近公共祖先是节点 3。 示例 2:输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5
和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。说明:
所有节点的值都是唯一的。 p、q 为不同节点且均存在于给定的二叉树中。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof
思路
- 根节点本身是否是p或者q当中的某个节点
- 递归根的左和根的右
2.1 左右两边都不为空:root是公共祖先
2.2 左边不为空,右边为空:左边第一次找到的节点就是公共祖先
2.3 左边为空,右边不为空:右边第一个节点就是公共祖先 - 如果都没有,则返回null
代码-递归
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root == q || root == p) return root;
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(left != null && right != null) return root;
if(left != null) return left;
if(right != null) return right;
return null;
}
}
以上是关于总结所有有关二叉树公共祖先问题的主要内容,如果未能解决你的问题,请参考以下文章
二叉树有关习题整理145二叉树的后序遍历 94二叉树的中序遍历 572另一棵树的子树 236二叉树的最近公共祖先 JZ36二叉搜索树与双向链表 - 牛客