剑指offer68-1(LeetCode235题)二叉搜索树的最近公共祖先

0. 题目来源

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree

1. 题目描述

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

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

2. 问题分析

做题分析题目非常重要,要理解清楚题目要表达的意思,以及题中出现定义的含义。
有两个注意点:

  • 题目中二叉树为二叉搜索树,即左子树中所有节点的值一定小于根节点,右子树中所有节点的值一定大于根节点,所以在搜索的时候可以根据值的大小来选择在左子树或者右子树中搜索;
  • 题目中出现了最近公共祖先的定义,结合图片,假如从根节点开始搜索,可以得到如下结论:
    • 如果两个节点值都小于根节点,说明他们都在根节点的左子树上,我们往左子树上找
    • 如果两个节点值都大于根节点,说明他们都在根节点的右子树上,我们往右子树上找
    • 如果一个节点值大于根节点,一个节点值小于根节点,说明他们一个在根节点的左子树上一个在根节点的右子树上,那么此时根节点就是他们的最近公共祖先节点

3. 代码实现

有了2中的思路,可以用递归和非递归两种方法实现,具体分析过程请参考

  1. 非递归方法,即迭代搜索:
public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 先让p节点的值小于q,这样判断边界条件时就只用判断一个
        if (p.val > q.val){
            TreeNode temp = p;
            p = q;
            q = temp;
        }
        // 根节点不为空时才判断
        while (root != null){
            if (root.val < p.val) //此时,根节点值比最小的还要小,说明p和q都在右子树中
                root = root.right;
            else if (root.val > q.val)//此时,根节点值比最大的还要大,说明p和q都在左子树中
                root = root.left;
            else  // 此时找到了公共祖先
                break;;
        }
        return root;
    }
}

提交结果:
在这里插入图片描述
2. 递归搜索:

public class Solution2 {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null)
            return null;
		// 先使得p的值小于q的值
        if (p.val > q.val){
            TreeNode temp = new TreeNode();
            temp = p;
            p = q;
            q= temp;
        }
        TreeNode node = helper(root, p, q);
        return node;
    }

    private TreeNode helper(TreeNode root, TreeNode p, TreeNode q){
        if (root.val < p.val){ // 比最小的还要小,说明p和q都在右子树中
            return helper(root.right,p,q);
        }else if (root.val > q.val){ // 比最大的还要大,说明p和q都在左子树中
            return helper(root,p,q);
        }else
            return root;
    }
}

提交结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值