剑指Offer 面试题68 - I. 二叉搜索树的最近公共祖先(Java代码)

二叉搜索树简介

二叉搜索树,也称二叉查找树、二叉排序树。英文名为 Binary Search Tree(即 BST)。

二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势,所以应用十分广泛。

二叉搜索树 定义如下:

它或者是一棵空树,或者是具有下列性质的二叉树:
它的左子树不空则左子树上所有结点的值均小于它的根结点的值
它的右子树不空则右子树上所有结点的值均大于它的根结点的值
它的左、右子树也分别为二叉排序树

一颗 真实 的二叉搜索树
在这里插入图片描述

二叉搜索树的特性

熟悉二叉搜索树的特性是我们解题的关键,看图
在这里插入图片描述

  • 二叉搜索树中,任意两个节点的值都不相等

    二叉搜索树中的每一个节点都相当于把原有的取值范围,切分为两份(有点眼熟,二分法!)

  • 左子树中的值,永远小于父节点。右子树中的值,永远大于父节点

    节点node的左孩子节点leftson的右孩子 grandson,依然是属于该节点node的左子树。
    leftson.val<grandson.val<node.val;

题目

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

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

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

在这里插入图片描述

剪枝法(五行代码解决)

如果能理解上一种解法的话,那么下面的这种解法,很容易理解了。

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 需要利用二叉搜索树的特性解题
        
        // 如果当前节点大于两个节点的值,说明目标节点在左子树,剪枝
        if(root.val > p.val && root.val > q.val)
            return lowestCommonAncestor(root.left, p, q);
        // 目标节点在右子树,剪枝
        if(root.val < p.val && root.val < q.val)
            return lowestCommonAncestor(root.right, p, q);
        // 如果上面两个if都没有走,就说明 root.val 的值介于 p和q的值之间[p,q]
        // 那么当前节点要么等于p或q中的一个,要么p在左子树,q在右子树,无论怎样它都是祖先
        return root;
    }
}
  • 如果当前节点root的值要大于两个指定节点的值,说明那两个指定节点肯定存在于,当前节点的左孩子中。
  • 如果当前节点root的值要小于两个指定节点的值,说明那两个指定节点肯定存在于,当前节点的右孩子中
  • 以上两种情况都不满足,说明当前节点root的值,介于 [lowwer, upper] 之间,当前节点root的左右孩子中各存在一个指定节点当前节点root是其中一个指定的节点(另一个节点在左/右孩子中)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值