题目
难度:★★☆☆☆
类型:二叉树
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
说明:
所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉搜索树中。
示例
例如,给定如下二叉搜索树: 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, 因为根据定义最近公共祖先节点可以为节点本身。
解答
这道题需要对二叉搜索树的定义有比较深刻的理解,二叉搜索树的所有结点,左子树上的结点的值都比该结点小,而右子树上的所有结点的值都比该结点大。
假设输入两个结点p,q的公共祖线结点是r,则根据二叉搜索树的特点,一定满足:
r.val > p.val 且r.val < q.val;
或者:
r.val < p.val且r.val > q.val;
以上判别式的紧凑写法是:
(r.val - p.val) * (r.val - q.val) < 0
因此我们可以设置循环,当满足条件(r.val - p.val) * (r.val - q.val) > 0时执行:如果p的值大于r的值,则查找结点变为当前结点的右子树,否则为左子树。
class Solution:
def lowestCommonAncestor(self, root, p, q):
while (root.val - p.val) * (root.val - q.val) > 0:
if p.val > root.val:
root = root.right
else:
root = root.left
return root
如有疑问或建议,欢迎评论区留言~