本文首发于我的博客:https://belindayang.cn/
寻找二叉搜索树的两个结点的最近公共父结点
一、二叉搜索树定义
是指一棵空树或者具有下列性质的二叉树:
若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
任意节点的左、右子树也分别为二叉查找树;
没有键值相等的节点
参考链接:维基百科
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-STpTQRE5-1583564382162)(/images/tree.png)]
二、二叉搜索树特点
中序遍历二叉搜索树 可以得到一个升序序列
三、算法思路:
算法思路1:以普通树解
递归思想
1 判断根结点是否等于p 或者 q 如果是,返回根结点的值
2 递归 判断左右子树是否有结点等于p或者q
3 返回非空子树的结点继续递归 如果左右子树都不为空 说明当前根结点是公共父节点 返回当前根结点
需要遍历每个结点1次 时间复杂度 为o(n)
代码如下
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 not root or root == p or root == q:
return root
leftnode = self.lowestCommonAncestor(root.left, p, q)
rightnode = self.lowestCommonAncestor(root.right, p, q)
if leftnode == None:
return rightnode
elif rightnode == None:
return leftnode
return root
算法思路2:
根据二叉搜索树的定义,左子树上的每个结点势必小于根节点,右子树上的每个结点势必大于根结点。
由此可以判定,
如果p和q都小于根结点,则p和q都在左子树
p和q都大于根结点,则p和q都在右子树
否则说明根结点则为所求公共父节点
代码如下
def lowestCommonAncestor2(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
node=root
while node:
if p.val<node.val and q.val<node.val:
node=node.left
elif p.val>node.val and q.val>node.val:
node=node.right
else:
return node
该方法的时间复杂度为o(n) 空间复杂度为o(1)
体会:
巧用二叉搜索树的特点可以使得算法思路变得清晰简单
欢迎关注公众号:pipi的奇思妙想