二叉树的最近公共祖先

二叉树的最近公共祖先

1. 题意

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

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

在这里插入图片描述

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

在这里插入图片描述

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

2. 思路

作为一个公共父节点,它应该有以下特征:

  • 如果该节点既不是 p p p 又不是 q q q,那么 p p p q q q 一定分别存在于 该节点的左右子树
  • 如果该节点是其中一个节点 p p p q q q,那么,该节点的左子树或右子树必然包含 q q q p p p

在官方题解中:
使用 l s o n lson lson 表示左子树包含 p p p q q q, 使用 r s o n rson rson 表示右子树包含 p p p q q q
而根据以上的特征,父节点所满足的条件应该是:
( l s o n & & r s o n ) ∣ ∣ ( ( r o o t . v a l = = q . v a l ∣ ∣ r o o t . v a l = = p . v a l ) & & ( l s o n ∣ ∣ r s o n ) ) (lson \&\& rson) ||((root.val == q.val || root.val == p.val) \&\& (lson || rson)) (lson&&rson)((root.val==q.valroot.val==p.val)&&(lsonrson))

3. 实现

正是基于以上特征,采用递归的方式进行深度优先搜索

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private TreeNode ans;

    public Solution() {
        this.ans = null;
    }

    private boolean dfs(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null)
            return false;

        //左右子树是否包含 p q 节点
        boolean lson = dfs(root.left,p,q);
        boolean rson = dfs(root.right,p,q);

        if ((lson && rson) || ((root.val == q.val) || (root.val == p.val)) && (lson || rson))
            this.ans = root;

        return lson || rson || root.val == q.val || root.val == p.val;
    }

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        this.dfs(root,p,q);
        return this.ans;
    }
}

4. 转载链接

链接: leetcode 236. 二叉树的最近公共祖先

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值