当前位置: 首页 > 知识库问答 >
问题:

基于递归的二叉树最低公共祖先

郦何平
2023-03-14

我试图通过自顶向下递归实现二叉树最低公共祖先(LCA)问题的解决方案。

我使用的方法是:

想法:找到在任一子树中有一个所需节点的节点,而另一个所需节点是相反的子树。

PSEUDOCODE
1. If the value of root is equal to either of the desired node's value, 
   the root is the LCA.
2. Search in the left subtree for either node.
3. Search in the right subtree for either node.
4. If neither of them contains any of the two nodes,
   the nodes do not exist in the tree rooted at the root node.
5. If each of them contains one node,
   the root is the LCA.
6. If either one of them contains a node,
   return it to the root.

以下是确切的实现:

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

    def __repr__(self):
        return 'TreeNode({}, {}, {})'.format(self.val, self.left, self.right)

def lowestCommonAncestor(root, p, q):
    """
    :type root: TreeNode
    :type p: TreeNode
    :type q: TreeNode
    :rtype: TreeNode
    """
    if root is None:
        return None

    if p.val == root.val or q.val == root.val:
        return root

    left_subtree = lowestCommonAncestor(root.left, p, q)
    right_subtree = lowestCommonAncestor(root.right, p, q)

    if left_subtree is None and right_subtree is None:
        return None

    if left_subtree is not None and right_subtree is not None:
        return root

    if left_subtree is None:
        return right_subtree
    else:
        return left_subtree

例如:

root = TreeNode(2)
root.left = TreeNode(3)
root.left.left = TreeNode(1)
root.right = TreeNode(5)
root.right.left = TreeNode(7)
root.right.right = TreeNode(1)
print(lowestCommonAncestor(root, TreeNode(1), TreeNode(7)))

这将返回树的根作为结果。结果=TreeNode(2)

共有1个答案

易元青
2023-03-14

您有一些问题:1)为什么要检查Node.val?您应该能够直接比较一个节点和另一个节点。当您有一个具有相同值的多个节点的树时,这应该可以解决问题...假设这是您唯一的问题。

2)如果左子树非空,右子树非空,为什么要返回root?当然,在许多情况下,这将返回root。这通常不是我们想要的行为。

您可能希望从头开始重新思考您的算法(您有一些不错的想法,但现在您看到您犯了一些错误,并且由于这个问题相当简单/直接,重新思考可能更有好处)。

建议:由于这个问题是一个树上的问题,并且与搜索/路径有关,所以考虑寻找从节点p到节点Q的路径的问题。我们知道,在一棵树中,任意两个节点都有一条路径(根据定义,这只是从树是一个连通的无环图这一事实中得出的)。

在返回到基本情况之后,或者在返回到基本情况之后,您可能希望创建一个数据结构来在循环中存储被访问的节点,然后测试一些条件,并可能递归更多(本质上是DFS方法与BFS方法相比,而BFS方法使用显式记忆/添加内存,而DFS使用堆栈来记住事情)。

 类似资料:
  • 问题内容: 这是一个受欢迎的面试问题,我唯一可以找到的有关该主题的文章是TopCoder的文章。对我来说不幸的是,从访谈答案的角度来看,它看起来过于复杂。 除了绘制到两个节点的路径并推导祖先之外,没有其他更简单的方法了吗?(这是一个很流行的答案,但是面试题有一个变体,要求一个固定的空格答案)。 问题答案: 恒定空间答案:(尽管不一定有效)。 有一个函数findItemInPath(int inde

  • 如果我拆分while循环,有什么不同吗?谢了!

  • 68.1 二叉查找树 题目链接 Leetcode : 235. Lowest Common Ancestor of a Binary Search Tree 解题思路 在二叉查找树中,两个节点 p, q 的公共祖先 root 满足 root.val >= p.val && root.val <= q.val。 // java public TreeNode lowestCommonAncestor

  • 我的问题是:“这是已知算法的已知问题吗?”。我怀疑是。它似乎非常类似于拓扑排序。我有一个基于合并排序的算法的想法,但如果已知的算法已经存在,就没有理由提出我自己的算法。

  • 我只用if语句解决了这个问题。它可以用其他各种方法来解决。我刚刚开始编程,所以我想不出使用任何其他数据结构来解决这个问题。 我的问题: 如何在各种方法中选择最好的方法?和我的直接天真方法相比,这种最佳方法的优点/缺点是什么。 不仅针对这个问题,总的来说。如何解决任何问题? 我的代码: 问题链接:https://www.hackerrank.com/challenges/binary-search-

  • 我读了一个算法来寻找二叉树中两个节点之间的距离。 这段代码在二叉树中找到(从根到给定节点的1个距离)。 我不明白的是,“x”有两个值,一个来自左子树,另一个来自右子树,它如何知道返回哪个值 例如,如果树类似于: 然后调用, 那么,在语句“”中,它如何返回正确的x值?