Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Given binary search tree: root = [6,2,8,0,4,7,9,null,null,3,5]
_______6______
/ \
___2__ ___8__
/ \ / \
0 _4 7 9
/ \
3 5
Example 1:
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.
. Example 2:
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
Output: 2
Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself
according to the LCA definition.
Note:
- All of the nodes' values will be unique.
- p and q are different and both values will exist in the BST.
LeetCode:链接
LCA(Least Common Ancestors),即最近公共祖先,指对于有根树 T 的两个结点 u 、v ,最近公共祖先 LCA(T,u,v)表示一个结点 x, 满足 x 是 u、v 的祖先且 x 的深度尽可能大。
第一种方法:根据二叉搜索树的性质,对于树中从root开始的节点:如果p和q的值都小于root的值,那么他们的最低公共祖先一定在root的左子树;如果p和q的值都大于root的值,那么他们的最低公共祖先一定在root的右子树;其他情况则说明最低公共祖先就是root节点,如此循环判断即可。
# 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
"""
while root:
if p.val > root.val and q.val > root.val:
root = root.right
elif p.val < root.val and q.val < root.val:
root = root.left
else:
return root
第二种方法:同第一种方法,只不过是用递归实现。
# 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
"""
if root == None:
return None
if p.val < root.val and q.val < root.val:
return self.lowestCommonAncestor(root.left, p, q)
elif p.val > root.val and q.val > root.val:
return self.lowestCommonAncestor(root.right, p, q)
else:
return root
第三种做法:通用的做法。是先分别找到从根节点到两个结点的路径,根据这两个路径找到最低公共祖先。因为是二叉搜索树,所以不需要BFS或DFS遍历节点找路径。
# 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
"""
pathp = self.findpath(root, p)
pathq = self.findpath(root, q)
for i in range(min(len(pathp), len(pathq))):
'''要找到最深的LCA'''
if pathp[i] == pathq[i]:
res = pathp[i]
return res
def findpath(self, root, p):
path = []
'''必须是结点不同'''
while root != p:
path.append(root)
if p.val < root.val:
root = root.left
elif p.val > root.val:
root = root.right
path.append(p)
return path