给你一个有根节点的二叉树,找到它最深的叶节点的最近公共祖先。
回想一下:
- 叶节点 是二叉树中没有子节点的节点
- 树的根节点的 深度 为
0
,如果某一节点的深度为d
,那它的子节点的深度就是d+1
- 如果我们假定
A
是一组节点S
的 最近公共祖先,S 中的每个节点都在以A
为根节点的子树中,且A
的深度达到此条件下可能的最大值。
示例 1:
输入:root = [1,2,3]
输出:[1,2,3]
示例 2:
输入:root = [1,2,3,4]
输出:[4]
示例 3:
输入:root = [1,2,3,4,5]
输出:[2,4,5]
提示:
- 给你的树中将有 1 到 1000 个节点。
- 树中每个节点的值都在 1 到 1000 之间。
解题思路
首先不难想到暴力法,也就是先找到最深的叶子节点,然后再找到叶子节点的公共祖先。如果找到最深的叶子节点?如何找公共祖先?这实际上是leetcode
之前的几个问题
Leetcode 102:二叉树的层次遍历(最详细解决方案!!!)
Leetcode 236:二叉搜索树中第K小的元素(最详细的解法!!!)
我们知道叶子节点的个数可能是一个,也可能是许多个。那么一个叶子节点的话,我们直接返回那个叶子节点即可。如果有许多个怎么办?我们只需返回最左边和最右边叶子节点的最近公共祖先即可。接下来就是复制代码了
class Solution:
def lcaDeepestLeaves(self, root: TreeNode) -> TreeNode:
le = self.levelOrder(root)
if len(le[-1]) == 1:
return le[-1][0]
return self.lowestCommonAncestor(root, le[-1][0], le[-1][-1])
def levelOrder(self, root):
ret = list()
if not root:
return ret
from queue import Queue
q = Queue()
q.put((root, 0))
while not q.empty():
node, level = q.get()
if level == len(ret):
ret.append([])
ret[level].append(node)
if node.left != None:
q.put((node.left, level + 1))
if node.right != None:
q.put((node.right, level + 1))
return ret
def lowestCommonAncestor(self, root, p, q):
if not root or 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
return left if left else right
上面的代码是可以通过的,但是非常的臃肿。我们一直说对于树型问题首先考虑递归,那么这个问题怎么通过递归来做呢?通过前序遍历访问整颗二叉树,每次返回当前整个树的叶子节点的最大深度d
和叶子节点的最近公共祖先x
。
我们先递归求解出左子树的ld
和lx
和右子树的rd
和rx
(分别对应最大深度和最近公共祖先)。那么当ld < rd
的时候,此时树的最大深度就是rd+1
,此时的最深叶节点的最近公共祖先自然就是rx
。当ld > rd
的时候,此时树的最大深度就是ld+1
,此时的最深叶节点的最近公共祖先自然就是lx
。当ld == rd
的时候,此时树的最大深度就是ld+1
或者rd+1
,此时的最深叶节点的最近公共祖先自然就是root
。
最后思考边界情况,也就是当root==None
的时候,此时的深度就是0
,公共祖先就是None
class Solution:
def lcaDeepestLeaves(self, root: TreeNode) -> TreeNode:
def dfs(root):
if not root:
return 0, None
l, r = dfs(root.left), dfs(root.right)
if l[0] < r[0]:
return r[0] + 1, r[1]
elif l[0] > r[0]:
return l[0] + 1, l[1]
else:
return l[0] + 1, root
return dfs(root)[1]
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!