leetcode 236. Lowest Common Ancestor of a Binary Tree(python)

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

描述

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
复制代码

Note:

The number of nodes in the tree is in the range [2, 10^5].
-10^9 <= Node.val <= 10^9
All Node.val are unique.
p != q
p and q will exist in the tree.
复制代码

解析

根据题意,给定一棵二叉树,找出树中两个给定节点的最低共同祖先(LCA)。根据维基百科 LCA 的定义:最低共同祖先被定义为两个节点 p 和 q 之间的最低节点,即 T 中同时具有 p 和 q 作为后代的节点(我们允许一个节点是它自己的后代)。看了几个例子之后应该就会理解 LCA 的含义了。这道题最简单的解法就是暴力找到根节点到 p 的路径和根节点到 q 的路径,然后找出分叉的节点,那就是 LCA ,但是这种解法时间复杂度在于找 p 或者 q ,时间复杂度为 O(n) ,尽管可以成功通过,但是因为要存两条途径,空间复杂度会变成 O(logn)。

解答

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
        """
        result = []
        def dfs(root, path, target):
            if not root:
                return 
            if root.val == target.val:
                path.append(root.val)
                result.append(path)
            if root.left:
                dfs(root.left, path+[root.val], target)
            if root.right:
                dfs(root.right, path+[root.val], target)
        dfs(root, [], p)
        dfs(root, [], q)
        p_path = result[0]
        q_path = result[1]
        idx = 0
        while idx < min(len(p_path), len(q_path)):
            if p_path[idx] != q_path[idx]:
                return TreeNode(p_path[idx-1])
            idx += 1
        return TreeNode(p_path[idx-1])
        	      
		
复制代码

运行结果

Runtime: 2456 ms, faster than 5.01% of Python online submissions for Lowest Common Ancestor of a Binary Tree.
Memory Usage: 418.2 MB, less than 5.06% of Python online submissions for Lowest Common Ancestor of a Binary Tree.
复制代码

解析

另外我们可以定义 dfs 为某个子树中包含了多少个 p 或者 q ,如果没有包含 p 或者 q 则返回 0 ,如果只包含了 p 或者 q 中的任意一个返回 1 ,如果都包含则返回 2 。因为是顶部向下递归,返回结果的时候是从下往上,所以当我们第一次碰到 dfs 返回 2 的某个节点,则肯定是 LCA 。

解答

class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution(object):
    def __init__(self):
        self.result = None
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        def dfs(root, p, q):
            if not root: return 0
            left = dfs(root.left, p, q)
            right = dfs(root.right, p, q)
            self_ = 1 if (p == root or q == root) else 0
            count = left + right + self_
            if count == 2 and not self.result:
                self.result = root
            return count
        dfs(root, p, q)
        return self.result	
复制代码

运行结果

Runtime: 68 ms, faster than 63.65% of Python online submissions for Lowest Common Ancestor of a Binary Tree.
Memory Usage: 29.9 MB, less than 8.97% of Python online submissions for Lowest Common Ancestor of a Binary Tree.
复制代码

原题链接:leetcode.com/problems/lo…

您的支持是我最大的动力

猜你喜欢

转载自juejin.im/post/7079596238277967909