二叉搜索树简介
二叉搜索树,也称二叉查找树、二叉排序树。英文名为 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
是其中一个指定的节点(另一个节点在左/右孩子中)