https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
示例 2:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。
说明:
所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。
# 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
"""
m = {}
def dfs(root):
if root:
if root.left:
m[root.left] = root
if root.right:
m[root.right] = root
dfs(root.left)
dfs(root.right)
dfs(root)
l1, l2 = p, q
while l1 != l2:
l1 = m.get(l1, None) if m.get(l1, None) is not None else q
l2 = m.get(l2, None) if m.get(l2, None) is not None else p
return l1
思路:
由于每个节点只有唯一一个父节点,我们可以使用到字典的value-key的形式(节点-父节点)字典中预置根节点的父节点为None。字典建立完成后,二叉树就可以看成一个所有节点都将最终指向根节点的链表了。于是在二叉树中寻找两个节点的最小公共节点就相当于,在一个链表中寻找他们相遇的节点。
作者:mian-mian-sir
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/shi-yong-zi-dian-cun-chu-shuang-qin-jie-dian-by-mi/
上面代码中dfs为深度遍历二叉树,建立子节点指向根节点的字典。其中根节点root我没建立,后面可以默认None,然后重点来了,将两个子节点分别同时寻找它的根节点,如果两个节点能够相等,说明已经找到根节点,如果一个节点发现没有父节点,说明是上面图示的情况,即一个节点离LCA近,一个离LCA远。那么我们开始遍历每个节点的根节点,当l2已经到达根节点root时,l1还没有到,并且此刻l1和l2的距离和一开始l1,l2距离是一样的,那么此时将l1初始的位置赋值给l2,继续遍历;当l1到达根节点时,l2达到到达与初始l2相同的距离(注意不是相同的位置,是距离根节点一样的距离),此时将l2的初始位置赋值给l1,那么此时l1和l2距离LCA就是一样的距离了,那么现在只要两个节点继续遍历下去就肯定能找到LCA。
此时将另一个节点赋值给该节点,然后继续寻找父节点;之后另一个节点也会发现没有父节点,则将