【问题标题】:Lowest Common Ancestor- Code Explain最低共同祖先 - 代码解释
【发布时间】:2015-10-06 18:35:52
【问题描述】:

中序和后序遍历的 LCA 很容易被我实现和理解。

但是,有一种自下而上的递归方法。

网上看了下代码,一行没看懂:

代码如下:

public Node lowestCommonAncestor(int val1, int val2,Node root){
    if(root == null){
        return null;
    }
    if(root.data == val1 || root.data == val2){
        return root;
    }

    Node left = lowestCommonAncestor(val1, val2, root.left);
    Node right = lowestCommonAncestor(val1, val2, root.right);

    if(left != null && right != null){
        return root;
    }
    return left != null ? left : right;
}

val1 和 val2 是需要找到 LCA 的两个节点的值。

最后一行是我卡住的地方。

return left != null ? left : right;

谁能解释一下?

谢谢。

【问题讨论】:

    标签: algorithm binary-tree lowest-common-ancestor


    【解决方案1】:

    这是(某种)朴素方法的巧妙实现,但实现的是自上而下而不是标准的自下而上。我们试着分析一下lowestCommonAncestor(int val1, int val2,Node root)返回了什么。

    如果在root 的左子树中找到val1val2 中的至少一个,则left 将不为空。类似地,当且仅当在root 的右子树中找到val1val2 中的至少一个时,right 才会不为空。显然,当且仅当在左子树中找到val1val2 之一并且精确 找到@987654332 之一时,if 语句if(left != null && right != null){ 才会为真@ 和 val2 在右子树中找到。因此,这只会发生在val1val2 的最低共同祖先(如果需要,请绘制图片)。对于此节点,将返回根。对于所有其他节点,该函数将在左侧或右侧子树中返回lowestCommonAncestor,具体取决于哪个不为空,或者如果两者都为空,则为空。

    因此对于 LCA 上方的所有节点,右和左中的一个将不为空(因为 val1val2 将在其中一个子树中),这将是 LCA 所在子树的根是。因此,对于 LCA 之上的所有节点,调用 lowestCommonAncestor 的返回值将是 LCA 本身。因此,对原始树根的调用将真正成为 LCA。

    【讨论】:

      【解决方案2】:
      // Method to find lowest common ancestor.
      public Node lowestCommonAncestor(int val1, int val2,Node root){
      
          // Base condition to terminate.
          if(root == null){
              return null;
          }
      
          // While traversing, if we found root itself equal to val1/val2.
          // Then, root should be the lowest common ancestor.
          if(root.data == val1 || root.data == val2){
              return root;
          }
      
          // If not, do post-order traversing. Means, left node, then right 
          // node, then root iteslf (current node.)
          Node left = lowestCommonAncestor(val1, val2, root.left);
          Node right = lowestCommonAncestor(val1, val2, root.right);
      
          // While traversing, if we reach to a state, when root itself has left and 
          // right both children, then, this is the lowest common ancestor of val1, 
          // and val2. return this root.
          if(left != null && right != null){
              return root;
          }
      
          // If, root has only one child either  left or right child, then start 
          // traversing into that child.
          // If, root has no child, in that case. Return null. Means this tree does    
          // not contain lowest common ancestor of val1, and val2.
          return left != null ? left : right;
      }
      

      我通过放置 cmets 来解释整个代码。我认为这会更有意义。请通过它。如果您仍有任何疑问,请随时提问。

      【讨论】:

        猜你喜欢
        • 2014-05-24
        • 1970-01-01
        • 1970-01-01
        • 2013-10-01
        • 1970-01-01
        • 2011-05-03
        • 1970-01-01
        • 1970-01-01
        • 2011-07-28
        相关资源
        最近更新 更多