问题描述
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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
[6, 2, 8, 0, 4, 7, 9, null, null, 3, 5]
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
补充说明:
给定了一个二叉搜索树,输入两个值,然后求这两个值得最近公共祖先。
方案分析
- 笔者做这个题的时候忘记了一个问题,导致感觉这个题写起来比较复杂。后来参照了别人的解法才恍然大悟。这里都说了是一个二叉搜索树,那么,这里隐藏的一个条件是搜索树是有序的!
- 父节点的值肯定是大于左孩子节点的值,小于右边孩子节点的值。那么给定两个要搜索的值,它的最近共同祖先的要不就是介于两个值之间,要不就是等于较小值。(等于是当两个搜索值在同侧的情况下,其中的一个搜索值作为自己本身的祖先)。
- 先上基本解法的递归写法。
python实现
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root, p, q):
if not root:
return
if root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
elif root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
else:
return root
方案分析2
- 递归并不是一个好的方法,换非递归的。
python实现2
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root, p, q):
while root:
if root.val > p.val and root.val > q.val:
root = root.left
elif root.val < p.val and root.val < q.val:
root = root.right
else:
return root
方案分析3
- 在别人那看到一个应用数学特性解决问题的方式,效率提升明显。
- 如果一个值x的大小介于a,b之间,那么(x-a)*(x-b)<=0。这不正是二叉搜索树的特性么。
python实现3
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root, p, q):
while (root.val-p.val)*(root.val-q.val) > 0:
if root.val > max(p.val, q.val):
root = root.left
else:
root = root.right
return root