236. 二叉树的最近公共祖先【190】

文章介绍了如何使用递归方法解决二叉树中找到两个指定节点的最近公共祖先的问题。通过判断当前节点是否为p或q,以及分别遍历左子树和右子树来确定最近公共祖先。如果左右子树都找到目标节点,那么当前节点就是最近公共祖先。
摘要由CSDN通过智能技术生成

难度等级:中等

上一篇算法:

103. 二叉树的锯齿形层序遍历【191】

力扣此题地址:

236. 二叉树的最近公共祖先 - 力扣(Leetcode)

1.题目:236. 二叉树的最近公共祖先

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

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

2.解题思路:

自顶向下遍历,用递归的方法,这里找到公共祖先分为两种情况:

1.p 和 q 在公共结点的两侧,则当前结点就是公共结点

2.公共结点为p 或 q 中的任何一个,另一个则为公共结点的子节点,那么p 或 q 则是公共结点。

代码思路:

(1)先判断root是否为null,或者root 为p 或 q中的任意一个,那么直接返回root,这里的root放在递归的时候就是当前结点。(root为null有两种情况,一种是树为null,第二种是叶子结点为null,也就是遍历完了,也没找到目标值)

(2)既然p 或 q 不是公共结点,那么分别递归左子树和右子树

(3)如果左子树和右子树都为null,说明左子树和右子树都遍历到叶子结点了,也没有找到目标值,那么返回null

(4)如果左子树为null,说明左子树没有目标值,那就返回右子树结果,反之亦然

(5)左子树和右子树都找到了目标结点,那就返回当前结点,当前结点就是公共结点

思路参考:236. 二叉树的最近公共祖先 - 力扣(Leetcode) 

小知识:一般涉及到树的算法,都是用递归来实现的。 

3.代码实现:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) {
            //只要当前根节点是p和q中的任意一个,就返回(因为不能比这个更深了,再深p和q中的一个就没了)
            return root;
        }
        //根节点不是p和q中的任意一个,那么就继续分别往左子树和右子树找p和q
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        //p和q都没找到,那就没有,返回null
        if(left == null && right == null) {
            return null;
        }

        //如果左子树没有p也没有q,就返回右子树的结果
        if (left == null) {
            return right;
        }
        //如果右子树没有p也没有q,就返回左子树的结果
        if (right == null) {
            return left;
        }

        //左右子树都找到p和q了,那就说明p和q分别在左右两个子树上,所以此时的最近公共祖先就是root
        return root;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值