题目:给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
_______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5
示例:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
说明:
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉搜索树中。
思路:将树的每一个节点的左右子节点加上其自身存入一个字典中,键为该节点。然后从根节点开始寻找q和p是否在某个节点的子节点集和中,直到找到包含pq的最小集合。
代码:
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
son_dic = {}
def get_son_dic(root):
if not root:
return []
else:
son_dic[root] = [root]+get_son_dic(root.left)+get_son_dic(root.right)
return son_dic[root]
result = root
while True:
if p in son_dic[result.left] and q in son_dic[result.left]:
result = result.left
elif p in son_dic[result.right] and q in son_dic[result.right]:
result = result.right
else:
return result
但是提交后没有通过,用Python写的关于链表和数的代码还不好在本地调试,没找到错误,!!!希望谁发现错误的还能给指出来,感激不尽。
但是!!!在看了别人的博客后发现,我漏掉了一个条件:所给的树是一棵二叉搜索树:树中任意节点的左子树中所有元素的值均小于该节点的值,该节点右子树中所有节点的值均大于该节点的值。有了这个条件,就好做一些了,对于p和q,不妨假设p<q(如果不是的话就交换p和q的值嘛),然后从根节点开始,逐层判断根节点是否在pq之间,若是则返回该节点,结束判断。
代码:
# 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, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
minn = min(p.val, q.val)
maxn = max(p.val, q.val)
if root is None:
return None
if minn <= root.val <= maxn:
return root
else:
l = lowestCommonAncestor(root.left, p, q)
r = lowestCommonAncestor(root.right, p, q)
if l:
return l
if r:
return r