Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
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).”
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Output: 3 Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 Output: 5 Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
Example 3:
Input: root = [1,2], p = 1, q = 2 Output: 1
Constraints:
- The number of nodes in the tree is in the range
[2, 105]
. -109 <= Node.val <= 109
- All
Node.val
are unique. p != q
p
andq
will exist in the tree.
题目给定一棵二叉树root, 和两个节点p和q,要求找出p和q的最低公共祖先(LCA)。
首先,对于一个节点node,在以下情况下会是节点p和q的最低公共祖先LCA:1)p和q落在节点node的左右子树上;2)节点node就是p和q的其中一个,另一个落在node左子树或右子树上。满足以上两种情况,节点node就是p和q的最低公共祖先。
另外,这题给的限制条件,使本题变得简单了很多,限制条件是:二叉树的节点个数一定大于2且所有节点都是唯一的;给定的两个节点p和q不相等且一定存在。
基本解题思路就是通过递归法遍历二叉树去找节点p和q,但是并需要遍历整棵树,由于题目说了p和q一定存在,这样我们在递归查找只要碰到一个节点等于p或q就可以停止不用继续递归查找该节点左右子树的所有节点,即使是这时另外一个节点还没找到。以下分析一下不需要查找的原因,假设我们碰到了节点p而这时q还没找到,那么q只有两种情况:1)q在p的左子树或右子树里;2)q在p及其左右子树之外的其他地方。如果q在p的左子树或右子树里那么p就是LCA;若果q不在p的左子树或右子树里,那么q一定是在p以上的某个父节点的另外一棵子树里,也就是p和q一定会分别在那个父节点的左右子树里,那么那个父节点就是LCA。
# 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':
if not root:
return None
if root == p or root == q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
if not left:
return right
return left