题目链接
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/
描述
给定二叉搜索树BST,找出该树中两个指定节点的最近公共祖先。
最近公共祖先的定义为:”对于树T的两个节点p和q,最近公共祖先表示为一个节点x,满足x是p、q的祖先且x的深度尽可能大。(一个节点也可以是它自己的祖先)。
所有节点的值都唯一,p、q为不同节点且均存在于给定的BST中。
示例
输入:root = [6,2,8,0,4,7,9,null,null,3,5],p=2,q=8
输出:6
节点2和8的最近公共祖先是6。
解题思路
二叉搜索树又被称为二叉查找树、二叉排序树。二叉搜索树具备以下几个性质:
(1) BST中每个节点如果存在左节点,左节点的值一定小于该节点的值。
(2) BST中每个节点如果存在右节点,右节点的值一定大于该节点的值。
(3)BST中任意一个非叶子节点的左子树中任意一个节点的值都小于当前节点值,右子树中任意一个节点的值都大于当前节点值。
(4)对BST进行中序遍历,可以得到一个升序序列。
找p和q的最近公共祖先时,我们要先把p和q给找到。因此我们仍采用递归的方式从上往下找,枚举所有可能:
p和q在root的同一子树中:
(1)如果p的节点值和q的节点值都小于root的节点值,那么p和q一定都在root的左子树,最近公共祖先一定在root的左子树上,因此下一步我们就递归root的左子树。
(2)如果p的节点值和q的节点值都大于root的节点值,那么p和q一定都在root的右子树里,最近公共祖先一定在root的右子树上,因此下一步我们就递归root的右子树。
p和q不在root的同一子树中:
(3)如果p和q在root的两侧,一个值大于root的值,一个值小于root的值,那么root就是最近公共祖先。
(4)root就等于p,q在p的子树中,此时root就是最近公共祖先;root就等于q,p在q的子树中,此时root是最近公共祖先。
因此如果判断p和q不在root的同一子树中,我们就可以返回root,root就是最近公共祖先。
Python实现
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
#这里没必要处理base case比如root为null的情况
#因为已经上一层递归传过来时,就确定p,q在以root为根节点的子树上,因此root不可能为None
#比如根据比较值确定p q都在root的左子树上,接下来就递归左子树,不会出现左子树为空的情况。
if(p.val < root.val and q.val < root.val):
return self.lowestCommonAncestor(root.left,p,q)
if(p.val > root.val and q.val > root.val):
return self.lowestCommonAncestor(root.right,p,q)
#p和q不在root的同一棵子树中。
else:
return root
拓展
leetcode-Python】-后序遍历+回溯-236. Lowest Common Ancestor of a Binary Tree