236.Lowest Common Ancestor of a Binary Tree

25 年 7 月 13 日 星期日
834 字
5 分钟

236. Lowest Common Ancestor of a Binary Tree

My solution exceed time limit:

python
# 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':
        ans = {root: 0}
        def isAncestor(root, d):
            if not root:
                return False
            # dfs 判断node在不在root的树中
            def dfs(root, node):
                if not root:
                    return False
                if root is node:
                    return True
                return dfs(root.left, node) or dfs(root.right, node)
            f = dfs(root, p) and dfs(root, q)
            if f == True:
                d > max(ans.values())
                ans[root] = d
            # isAncestor 向下递归root
            isAncestor(root.left, d+1)
            isAncestor(root.right, d+1)
            return f
        isAncestor(root, 0)
        a = {x: i for i, x in ans.items()}
        return a[max(a.keys())]

根据以上定义,若 root 是 p,q 的 最近公共祖先 ,则只可能为以下情况之一:

  1. p 和 q 在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);
  2. p=root ,且 q 在 root 的左或右子树中;
  3. q=root ,且 p 在 root 的左或右子树中;

二叉树最近公共祖先——递归解析

思路
通过递归对二叉树进行先序遍历,当遇到节点 pq 时返回。从底至顶回溯,当 p, q 在当前节点 root 的异侧时,root 即为最近公共祖先,向上返回 root

1. 终止条件

  • 越过叶节点
    • root == null 时,直接返回 null
  • 找到目标节点
    • root == proot == q 时,直接返回 root

2. 递推工作

  1. 递归调用左子树,返回值记为 left
  2. 递归调用右子树,返回值记为 right

3. 根据 leftright 的情况返回结果

  1. leftright 同时为空
    • 说明 root 的左右子树都不包含 p, q
    • 返回 null
  2. leftright 同时不为空
    • 说明 p, q 分别在 root 的左、右子树
    • 因此当前 root 就是最近公共祖先,返回 root
  3. left 为空,right 不为空
    • 说明 p, q 不在 root 的左子树中,直接返回 right
    • 细分两种情况:
      1. 只有 pq(假设为 p)在右子树,此时 right 指向 p
      2. p, q 都在右子树,此时 right 指向它们的最近公共祖先
  4. left 不为空,right 为空
    • 同理,说明 p, q 都不在右子树,直接返回 left

作者:Krahets 链接:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/solutions/240096/236-er-cha-shu-de-zui-jin-gong-gong-zu-xian-hou-xu/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

python
# 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':
        # 只要当前根节点是p和q中的任意一个,就返回(因为不能比这个更深了,再深p和q中的一个就没了)
        if not root or root == p or root == q:
            return root
        # 根节点不是p和q中的任意一个,那么就继续分别往左子树和右子树找p和q
        # left和right为 p 或者 q 或者 None
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        # p和q都没找到,那就没有
        if left == None and right == None:
            return None
        # 左子树没有p也没有q,就返回右子树的结果
        if left == None:
            return right
        # 右子树没有p也没有q就返回左子树的结果
        if right == None:
            return left
        # 左右子树都找到p和q了,那就说明p和q分别在左右两个子树上,所以此时的最近公共祖先就是root
        return root

文章标题:236.Lowest Common Ancestor of a Binary Tree

文章作者:Sirui Chen

文章链接:https://blog.siruichen.me/posts/236lowest_common_ancestor_of_a_binary_tree[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。