剑指offer 76. 树中两个结点的最低公共祖先

简介: 剑指offer 76. 树中两个结点的最低公共祖先

题目描述

给出一个二叉树,输入两个树节点,求它们的最低公共祖先。

一个树节点的祖先节点包括它本身。

注意:

  • 输入的二叉树不为空;
  • 输入的两个节点一定不为空,且是二叉树中的节点;


数据范围

树中节点数量 [0,500]。

样例

二叉树[8, 12, 2, null, null, 6, 4, null, null, null, null]如下图所示:
  8
 / \
12  2
   / \
  6   4
1. 如果输入的树节点为2和12,则输出的最低公共祖先为树节点8。
2. 如果输入的树节点为2和6,则输出的最低公共祖先为树节点2。


方法一:二叉树+递归 O(n)

这道题我们递归的去查找,分别去递归每个结点的左右子树,我们拿题目样例进行举例。


假如我们要寻找 12 和 4 的最低公共祖先,则会先从根结点 8 向下进行递归查找,首先递归左子树,发现 12 就已经是目标结点,故直接返回该结点。


而根结点 8 的右结点不是目标结点,所以会继续递归左右结点,而 2 左子树中没有目标结点,最终会返回 NULL 。但其右子树中有目标结点 4 ,故会返回 4 ,然后结点 2 又会向其父结点返回查找到的结点 4 。


至此,根结点 8 左右子树查找结果都不为空,所以结点 8 就是目标结点 12 和 4 的最低公共祖先。


我们再看个例子,假设要寻找 2 和 4 的最低公共祖先。同样从根结点 8 出发向下递归,发现左子树中没有目标结点,最终返回 NULL 。而右子树中遍历到第一个结点 2 就会直接返回,因为 2 已经是目标结点,所以根结点 8 会得到答案 2 ,这个 2 就是 2 和 4 的最低公共祖先。


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
      //如果没有遍历到p或q,最终会遍历到空结点,直接返回NULL
        if (!root)   return NULL;
        //如果遍历到p或者q,则直接返回
        if (p == root || q == root)    return root;
        //获得左右子树的遍历情况
        auto left = lowestCommonAncestor(root->left, p, q);
        auto right = lowestCommonAncestor(root->right, p, q);
    //如果两个子树的遍历结果都不为空,则说明当前结点就是最低公共结点
        if (left && right) return root;
        //如果右子树遍历结果为空,则说明右子树中没有目标结点或者答案在左子树中
        if (left && !right)    return left;
        //反之,左子树为空,则说明左子树中没有目标节点或者答案在右孩子中
        return right;
    }
};

欢迎大家在评论区交流~


目录
相关文章
|
6月前
【每日一题Day300】LC2236判断根结点是否等于子结点之和
【每日一题Day300】LC2236判断根结点是否等于子结点之和
33 0
|
6月前
二叉树查找值为x的结点、树的高度、第k层结点个数的代码实现
二叉树查找值为x的结点、树的高度、第k层结点个数的代码实现
计算左子树规模(结点个数),找出树的根结点
简单的计算公式教你找出左子树到底有多少个娃,也会与你一起寻找根结点,快来看看呀
计算左子树规模(结点个数),找出树的根结点
|
算法
【算法真题 一】满二叉搜索树求三个节点的最低公共祖先
【算法真题 一】满二叉搜索树求三个节点的最低公共祖先
105 0
剑指offer 54. 两个链表的第一个公共结点
剑指offer 54. 两个链表的第一个公共结点
71 0
|
Java 测试技术
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。(Java语言实现)
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。(Java语言实现)
169 0
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。(Java语言实现)
|
存储 Java
(Java)数据结构之树与二叉树(二叉树的四种遍历,获取结点个数,获取叶子结点个数,获取高度,获取第k层结点个数,查找值为val的结点,判断一棵树是否为完全二叉树(详述,图文并茂)
树是一种非线性的数据结构,它是由n个(n>=0)个有限节点组成一个具有层次关系的集合。它的形状像一颗倒挂的树,根在上,叶在下。
(Java)数据结构之树与二叉树(二叉树的四种遍历,获取结点个数,获取叶子结点个数,获取高度,获取第k层结点个数,查找值为val的结点,判断一棵树是否为完全二叉树(详述,图文并茂)
|
Java
输入一棵二叉树,判断该二叉树是否是平衡二叉树(Java版)/输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。(Java版)
输入一棵二叉树,判断该二叉树是否是平衡二叉树(Java版)/输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。(Java版)
135 0
AcWing 66. 两个链表的第一个公共结点
AcWing 66. 两个链表的第一个公共结点
71 0
AcWing 66. 两个链表的第一个公共结点