目录

二叉树的最近公共祖先

二叉搜索数的最近公共祖先

二叉树的最近公共祖先Ⅱ

二叉树的最近公共祖先Ⅲ

二叉树的最近公共祖先Ⅳ


二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 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。因为根据定义最近公共祖先节点可以为节点本身。

核心:后序遍历,是二叉树中回溯的体现!

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root==p || root==q ||root==nullptr)return root;TreeNode* left=lowestCommonAncestor(root->left,p,q);TreeNode* right=lowestCommonAncestor(root->right,p,q);if(left && right){return root;}else if(left==nullptr && right!=nullptr){return right;}else if(left!=nullptr && right==nullptr){return left;}else{return nullptr;}}
};

二叉搜索数的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 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, 因为根据定义最近公共祖先节点可以为节点本身。

利用BST的特性,左子树结点比根节点小,右子树结点比根节点大

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if((root->val-p->val) * (root->val-q->val) <=0){return root;}return lowestCommonAncestor(p->val<root->val?root->left:root->right,p,q);}
};

二叉树的最近公共祖先Ⅱ

给定一棵二叉树的根节点 root,返回给定节点 p 和 q 的最近公共祖先(LCA)节点。如果 p 或 q 之一 不存在 于该二叉树中,返回 null。树中的每个节点值都是互不相同的。

根据维基百科中对最近公共祖先节点的定义:“两个节点 p 和 q 在二叉树 T 中的最近公共祖先节点是 后代节点 中既包括 p 又包括 q 的最深节点(我们允许 一个节点为自身的一个后代节点 )”。一个节点 x 的 后代节点 是节点 x 到某一叶节点间的路径中的节点 y。

示例 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。根据共同祖先节点的定义,一个节点可以是自身的后代节点。

示例 3:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 10
输出: null
解释: 节点 10 不存在于树中,所以返回 null。

此题与基础的二叉树最近公共祖先的区别在于,如果p或q结点并不存在于树中,则要返回nullptr

class Solution {
public:bool findp=false;bool findq=false;TreeNode* dfs(TreeNode* root, TreeNode* p, TreeNode* q){if(root==nullptr)return root;TreeNode* left=dfs(root->left,p,q);TreeNode* right=dfs(root->right,p,q);if(left && right){return root;}if(root->val==p->val){findp=true;return root;}if(root->val==q->val){findq=true;return root;}return left==nullptr?right:left;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {TreeNode* ans=dfs(root,p,q);if(!findp || !findq){return nullptr;}return ans;}
};

二叉树的最近公共祖先Ⅲ

给定一棵二叉树中的两个节点 p 和 q,返回它们的最近公共祖先节点(LCA)。

每个节点都包含其父节点的引用(指针)。Node 的定义如下:

class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
}
根据维基百科中对最近公共祖先节点的定义:“两个节点 p 和 q 在二叉树 T 中的最近公共祖先节点是后代节点中既包括 p 又包括 q 的最深节点(我们允许一个节点为自身的一个后代节点)”。一个节点 x 的后代节点是节点 x 到某一叶节点间的路径中的节点 y。

示例 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,根据定义,一个节点可以是自身的最近公共祖先。
示例 3:

输入: root = [1,2], p = 1, q = 2
输出: 1

此题特点在于,没有直接给根节点,而是给了两个子节点的父指针,所以很简单,直接找到根节点,将问题转化为①即可。

/*
// Definition for a Node.
class Node {
public:int val;Node* left;Node* right;Node* parent;
};
*/class Solution {
public:Node* dfs(Node* root,Node* p,Node* q){if(root==nullptr || root==p || root==q){return root;}Node* left=dfs(root->left,p,q);Node* right=dfs(root->right,p,q);if(left && right){return root;}return left==nullptr?right:left;}Node* lowestCommonAncestor(Node* p, Node * q) {Node* root=p;while(root->parent!=nullptr){root=root->parent;}root=dfs(root,p,q);return root;}
};

二叉树的最近公共祖先Ⅳ

给定一棵二叉树的根节点 root 和 TreeNode 类对象的数组(列表) nodes,返回 nodes 中所有节点的最近公共祖先(LCA)。数组(列表)中所有节点都存在于该二叉树中,且二叉树中所有节点的值都是互不相同的。

我们扩展二叉树的最近公共祖先节点在维基百科上的定义:“对于任意合理的 i 值, n 个节点 p1 、 p2、...、 pn 在二叉树 T 中的最近公共祖先节点是后代中包含所有节点 pi 的最深节点(我们允许一个节点是其自身的后代)”。一个节点 x 的后代节点是节点 x 到某一叶节点间的路径中的节点 y。

示例 1:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], nodes = [4,7]
输出: 2
解释: 节点 4 和 7 的最近公共祖先是 2。
示例 2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], nodes = [1]
输出: 1
解释: 单个节点的最近公共祖先是该节点本身。

示例 3:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], nodes = [7,6,2,4]
输出: 5
解释: 节点 7、6、2 和 4 的最近公共祖先节点是 5。
示例 4:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], nodes = [0,1,2,3,4,5,6,7,8]
输出: 3
解释: 树中所有节点的最近公共祖先是根节点。

不同的是,这次不再是只寻找两个孩子的父亲结点,而是寻找一堆孩子的父亲节点,因此唯一的区别就是在递归终止条件中要对所有孩子结点进行for遍历一次,只要当前根节点与其中一个孩子结点相同,则返回root。最后(也就是最顶层)的root,它的孩子一定包含了所有的孩子节点。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, vector<TreeNode*> &nodes) {for(auto &node:nodes){if(root==node || root==nullptr){return root;}}TreeNode* left=lowestCommonAncestor(root->left,nodes);TreeNode* right=lowestCommonAncestor(root->right,nodes);if(left && right)return root;return left!=nullptr?left:right;}
};

二叉树的最近公共祖先、二叉搜索数的最近公共祖先相关推荐

  1. 6-3 二叉搜索树中的最近公共祖先 (25 分)

    大一下半期数据结构 二叉搜索树中的最近公共祖先 在一棵树T中两个结点u和v的最近公共祖先(LCA),是树中以u和v为其后代的深度最大的那个结点.现给定某二叉搜索树(BST)中任意两个结点,要求你找出它 ...

  2. 验证二叉搜索数—leetcode98

    给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索 ...

  3. LeetCode 第 1373 题:二叉搜索子树的最大键值和

    LeetCode 第 1373 题:二叉搜索子树的最大键值和 题目 1373. 二叉搜索子树的最大键值和 的要求是,给你一颗以 root 为根的二叉树,要求返回任意二叉搜索子树的最大键值和. 首先要注 ...

  4. Suzy找到实习了吗 Day 21 | 二叉树进行中:530. 二叉搜索树的最小绝对差,501. 二叉搜索树中的众数,236. 二叉树的最近公共祖先

    530. 二叉搜索树的最小绝对差 题目 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 .差值是一个正数,其数值等于两值之差的绝对值. solution # Defi ...

  5. 代码随想录算法训练营第22天 二叉树 java :235. 二叉树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

    文章目录 LeetCode 236. 二叉树的最近公共祖先 题目讲解 思路 LeetCode 701.二叉搜索树中的插入操作 题目讲解 思路 LeetCode 450.删除二叉搜索树中的节点 题目讲解 ...

  6. 二叉树part8 | ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

    文章目录 235. 二叉搜索树的最近公共祖先 思路 代码 困难 701.二叉搜索树中的插入操作 思路 代码 450.删除二叉搜索树中的节点 思路 代码 困难 今日收获 235. 二叉搜索树的最近公共祖 ...

  7. 二叉树(二):判断是不是二叉搜索树、判断是不是完全二叉树、判断是不是平衡二叉树、二叉搜索树的最近公共祖先、在二叉搜索树中找到两个节点的最近公共祖先、序列化二叉树、重建二叉树、输出二叉树的右视图

    目录 一.判断是不是二叉搜索树 1.1 题目 1.2 题解 二.判断是不是完全二叉树 2.1 题目 2.2 题解 三.判断是不是平衡二叉树 3.1 题目 3.2 题解 四.二叉搜索树的最近公共祖先 4 ...

  8. 二叉树中最大的二叉搜索子树

    问题描述 思路和代码 暴力方法是每个节点为根节点,然后判断以该节点为根节点的树是否是二叉搜索树,然后求规模最大的,这种方式的时间复杂度是O(N2)O(N^2)O(N2),空间复杂度是O(h)O(h)O ...

  9. 算法训练营 day20 二叉树 最大二叉树 合并二叉树 二叉搜索树中的搜索 验证二叉树

    算法训练营 day20 二叉树 最大二叉树 合并二叉树 二叉搜索树中的搜索 验证二叉树 最大二叉树 654. 最大二叉树 - 力扣(LeetCode) 给定一个不重复的整数数组 nums . 最大二叉 ...

最新文章

  1. linux grep 显示多行信息
  2. 一个DDOS病毒的分析(二)
  3. 你可能不知道的 docker 命令的奇淫怪巧
  4. C++学习之路 | PTA(天梯赛)—— L2-024 部落 (25分)(带注释)(并查集)(精简)
  5. 你应该知道的 Linux 命令行技巧
  6. easyui的datagrid和panel如何让标题动态改变?
  7. C++读取一整行字符串以及其他函数
  8. Jmeter 常用断言使用
  9. java jpanel 叠加_如何添加多个扩展JPanel到Java中的一个JFrame中?
  10. 在 Adobe AIR 中为不同屏幕尺寸的多种设备提供支持
  11. 超级计算机运行吃鸡,决赛圈的时候,如果两个人同时被手雷炸死该怎么办呢?...
  12. 返回0-9直接的随机数
  13. node.js核心模块实例应用,基于nods.js环境向json文件添加数据
  14. VMware虚拟机安装Win10
  15. 我有一个梦,叫“禾下乘凉梦“!
  16. 家用无线路由器哪个品牌好?程序员分享值得推荐的无线路由器
  17. 如何获取Intel网卡驱动的源代码
  18. Ubuntu安装Source Insight导入Android源码并设置仿IDEA主题Darcula
  19. jenkins环境配置
  20. 海关外贸企业大数据风控平台产品应用

热门文章

  1. 黑莓Java应用开发环境
  2. jq实现文字个数限制_js实现文本框输入文字个数限制代码
  3. L1-077 大笨钟的心情(分数 15)
  4. 操作系统实验二(银行家算法)
  5. JS轮播图(左右箭头切换、按钮切换、自动轮播)
  6. matlab 取余(rem)和取模(mod)的区别
  7. html错位排列,错位排列的一个计算公式
  8. 基于Labview的环境噪声测量系统
  9. Ubuntu - ctags
  10. aes128算法c语言实现,AES128 C语言实现