【LeetCode】236.二叉树的最近公共祖先 (Python)

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/

【LeetCode】236.二叉树的最近公共祖先 (Python)_第1张图片

上面代码中dfs为深度遍历二叉树,建立子节点指向根节点的字典。其中根节点root我没建立,后面可以默认None,然后重点来了,将两个子节点分别同时寻找它的根节点,如果两个节点能够相等,说明已经找到根节点,如果一个节点发现没有父节点,说明是上面图示的情况,即一个节点离LCA近,一个离LCA远。那么我们开始遍历每个节点的根节点,当l2已经到达根节点root时,l1还没有到,并且此刻l1和l2的距离和一开始l1,l2距离是一样的,那么此时将l1初始的位置赋值给l2,继续遍历;当l1到达根节点时,l2达到到达与初始l2相同的距离(注意不是相同的位置,是距离根节点一样的距离),此时将l2的初始位置赋值给l1,那么此时l1和l2距离LCA就是一样的距离了,那么现在只要两个节点继续遍历下去就肯定能找到LCA。

此时将另一个节点赋值给该节点,然后继续寻找父节点;之后另一个节点也会发现没有父节点,则将

你可能感兴趣的:(算法工程师笔试机构,Leetcode,Code)