【算法】解题总结:剑指Offer 86 在二叉树中找到两个节点的最近公共祖先、剑指Offer 68 二叉搜索树的最近公共祖先

JZ86 在二叉树中找到两个节点的最近公共祖先

(中等)

题目

描述
在这里插入图片描述

示例
输入:
[3,5,1,6,2,0,8,#,#,7,4],5,1
返回值:
3

思路

可用递归的思想,我们可以再写一个返回值和参数都为树结点类型的函数进行递归,让它最终返回待求o1、o2最近的祖先结点,在递归函数中,对左右子树都再次进行递归,若当前结点为空时我们肯定要终止并返回 null,因为此条递归线路并没有找到值为 o1 或 o2 的结点,而如果当前结点值等于给定的 o1 或 o2 时,我们也应该返回此结点,从而结束此条递归线路,因为此条递归线路中含有 o1 或 o2 参数值对应的结点,因为我们之前的递归是对根结点以及其下结点都进行了左右递归,因此我们最终会得到左右子树两边递归的结果返回情况,如果一边为空的话,那么待求公共祖先肯定在另一边,也就是返回另一边的递归结果即可,这个思想需要意会,文字不容易表述,而如果左边右边递归结果结点都不为空,那么说明 o1 或 o2 对应左右子树中的某个结点,那么我们返回当前结点即可,也就是 o1 或 o2 和当前结点构成的树的根结点。

实现

	/**
     * 递归解法
     *
     * @param root
     * @param o1
     * @param o2
     * @return
     */
    int o1 = 0;
    int o2 = 0;

    public int lowestCommonAncestor1(TreeNode root, int o1, int o2) {
        this.o1 = o1;
        this.o2 = o2;
        return search(root).val;
    }

    public TreeNode search(TreeNode node) {
        if (node == null || node.val == o1 || node.val == o2) return node;

        TreeNode leftNode = search(node.left);
        TreeNode rightNode = search(node.right);

        if (leftNode == null) return rightNode;
        if (rightNode == null) return leftNode;
        return node;
    }

在这里插入图片描述

JZ68 二叉搜索树的最近公共祖先

(中等)

题目

描述
在这里插入图片描述

示例1
输入:
{7,1,12,0,4,11,14,#,#,3,5},1,12
返回值:
7
说明:
节点1 和 节点12的最近公共祖先是7

示例2
输入:
{7,1,12,0,4,11,14,#,#,3,5},12,11
返回值:
12
说明:
因为一个节点也可以是它自己的祖先.所以输出12

思路

也可以用递归的思想,代码大体上和上述普通二叉树结构下的代码相似,由于本题是二叉搜索树,由于其结点值“左小右大”的特点,我们不必再根据左右子树递归线路的结果返回情况来判断待求公共祖先,而是可以之间在递归过程中判断是否 o1、o2 的值都小于当前结点值,那么自然就在左树,如果都大于,那么自然在右树,而一个大于一个小于,那么自然待求结点就是递归过程中的当前结点了。

实现

	int o1 = 0;
    int o2 = 0;

    public int lowestCommonAncestor(TreeNode root, int p, int q) {
        o1 = p;
        o2 = q;
        return search(root).val;
    }

    public TreeNode search(TreeNode node) {
        if (node == null || node.val == o1 || node.val == o2) return node;

        if (o1 < node.val && o2 < node.val) return search(node.left);
        if (o1 > node.val && o2 > node.val) return search(node.right);
        return node;
    }

在这里插入图片描述

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超周到的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值