当前位置:网站首页>236. 二叉树的最近公共祖先
236. 二叉树的最近公共祖先
2022-08-03 00:23:00 【ZNineSun】
打卡!!!每日一题
今天给大家带来一道树类型的题目,也是一道比较经典的深度优先遍历的题目
题目描述:236. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
题目示例:
题目大概可以分为以下几种情形:
- 如果两个节点中有任意一个是根节点,那么我们就可以直接返回根节点
- 如果两个节点在树的两侧,那么他们最近的公共祖先也只能是根节点
- 最难的情况便是两个节点在树的同一侧
对于p或q是根节点的情况,我们只需判断p或q是否和根节点相等即可
if (p.val == root.val || q.val == root.val) {
return root;
}
判断是否在树的两侧,我们只需划分左右子树即可
int rootIndex = allNodeVal.indexOf(root.val);
int pIndex = allNodeVal.indexOf(p.val);
int qIndex = allNodeVal.indexOf(q.val);
/**2.两个节点在树的两侧**/
if (pIndex < rootIndex && qIndex > rootIndex || pIndex > rootIndex && qIndex < rootIndex) {
return root;
}
两个节点在同一侧的话,我们需要用一个Hash表存储每个节点的所有父节点,然后获取p,q的父节点列表,因为我们需要层数最深的父节点 ,所以我们可以考虑采用中序遍历二叉树,这样的话层数最深的结点就会在链表的前面
public void dfs(TreeNode root) {
if (root == null) return;
if (root.left != null) {
parent.put(root.left.val, root);
dfs(root.left);
}
if (root.right != null) {
parent.put(root.right.val, root);
dfs(root.right);
}
}
完整代码如下:
package com.exercise.leetecode.problem.剑指offer.前中后序遍历;
import com.exercise.leetecode.common.TreeNode;
import java.util.*;
public class 二叉树的最近公共祖先_236 {
Map<Integer, TreeNode> parent = new HashMap<Integer, TreeNode>();
List<Integer> allNodeVal = new ArrayList<>();
TreeNode r;//存放根节点
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
/**1.说明其中有一个结点是根节点**/
if (p.val == root.val || q.val == root.val) {
return root;
}
//判断两个节点是否在同一侧
r = root;
dfs_in(root);
root = r;
boolean sig_p = false, sig_q = false;
int rootIndex = allNodeVal.indexOf(root.val);
int pIndex = allNodeVal.indexOf(p.val);
int qIndex = allNodeVal.indexOf(q.val);
/**2.两个节点在树的两侧**/
if (pIndex < rootIndex && qIndex > rootIndex || pIndex > rootIndex && qIndex < rootIndex) {
return root;
}
dfs(root);
List<TreeNode> pParent = new ArrayList<>();
pParent.add(p);
while (p != null) {
p = parent.get(p.val);
pParent.add(p);
}
List<Integer> qParent = new ArrayList<>();
qParent.add(q.val);
while (q != null) {
q = parent.get(q.val);
if (q != null) {
qParent.add(q.val);
}
}
for (TreeNode t : pParent) {
if (qParent.contains(t.val)) {
return t;
}
}
return null;
}
public void dfs_in(TreeNode root) {
if (root == null) {
return;
}
dfs_in(root.left);
allNodeVal.add(root.val);
dfs_in(root.right);
}
public void dfs(TreeNode root) {
if (root == null) return;
if (root.left != null) {
parent.put(root.left.val, root);
dfs(root.left);
}
if (root.right != null) {
parent.put(root.right.val, root);
dfs(root.right);
}
}
}
边栏推荐
猜你喜欢
随机推荐
解决错误:Optional int parameter ‘pageSize‘ is present but cannot be translated into a null value due to
DataGuard日常维护常见问题之数据同步异常
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
DB2数据库-获取表结构异常:[jcc][t4][1065][12306][4.26.14]CharConvertionException ERRORCODE=-4220,SQLSTATE=null
Auto.js special positioning control method cannot perform blocking operations on the ui thread, please use setTimeout instead
九零后程序员心声:互联网的同行们,别卷了,再卷人都卷没了
Nacos配置中心之事件订阅
2022 开放原子全球开源峰会 | 麒麟信安携手openEuler助力开源产业繁荣发展
Go高性能之方法接收器 - 指针vs值
即席查询—— Kylin使用
UE5 官方案例Lyra 全特性详解 8.如何用配置表初始化角色数据
dataBinding的import导入
新公链时代的跨链安全性解决方案
优秀论文以及思路分析01
async-await
Rasa 3.x study series - Rasa - Issues 4792 socket debug logs clog up debug feed study notes
开源聚力,共创未来 | 麒麟信安祝贺openKylin首个体验版正式发布!
Moco of Mock tools use tutorial
优秀论文以及思路分析02
【mysql知识点整理】--- order by 、group by 出现Using filesort原因详解