[解题报告]Lowest Common Ancestor最近公共祖先

题目:

Given the root and two nodes in a Binary Tree. Find the lowest common ancestor(LCA) of the two nodes.

The lowest common ancestor is the node with largest depth which is the ancestor of both nodes.

Example

For the following binary tree:

  4
 / \
3   7
   / \
  5   6

LCA(3, 5) = 4

LCA(5, 6) = 7

LCA(6, 7) = 7

思路:

解法1:

根节点和给的两个节点A、B结点的关系有种3.5情况

1、  A在根结点左边,B在根节点右边,则LCA是根结点

1.5、 根结点是A结点或者B结点,则LCA是根结点

2、  A和B都在左边,则将左边递归

3、  A和B都在右边,则将右边递归

需要一个辅助的函数来看一个结点是否是另一个结点的祖先。

这样的解法比较容易理解,但是效率低,会递归两次。。比较浪费

 

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */
public class Solution {
    /**
     * @param root: The root of the binary search tree.
     * @param A and B: two nodes in a Binary.
     * @return: Return the least common ancestor(LCA) of the two nodes.
     */
    public boolean isAncestor(TreeNode root, TreeNode node) {
        if (root == null) {
            return false;
        } else if (root == node) {
            return true;
        }
        
        return isAncestor(root.left, node) || isAncestor(root.right, node);
    }
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode A, TreeNode B) {
        // write your code here
        
        if (root == null) {
            return null;
        }
        // root 为A, 则最近公共祖先为root即A
        // root 为B,则最近公共祖先为root即B
        if (root == A || root == B) {
            return root;
        }
        boolean isAinleft = isAncestor(root.left, A);
        boolean isBinleft = isAncestor(root.left, B);
       
        //若都在左边,往左找;若都在右边往右找
        if (isAinleft && isBinleft) {
            return lowestCommonAncestor(root.left, A, B);
        } else if (!isAinleft && !isBinleft){
            return lowestCommonAncestor(root.right, A, B);
        }
        
        // 即一个在左一个在右,最近公共祖先为root
        return root;
    }
}

 

 

 

解法2:

分治法(divide and conquer)

优化下上面的方法,能否只递归一遍就能找到答案呢。

    // 在root为根的二叉树中找A,B的LCA:
    // 如果找到了就返回这个LCA,找到的情况root == A || root == B
    // 如果只碰到A,就返回A
    // 如果只碰到B,就返回B
    // 如果都没有,就返回null

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */
public class Solution {
    /**
     * @param root: The root of the binary search tree.
     * @param A and B: two nodes in a Binary.
     * @return: Return the least common ancestor(LCA) of the two nodes.
     */
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode A, TreeNode B) {
        // solution2
        if (root == null || root == A || root == B) {
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, A, B);
        TreeNode right = lowestCommonAncestor(root.right, A, B);
        
        if (left != null && right != null) {
            return root;
        }
        if (left != null) {
            return left;
        }
        if (right != null) {
            return right;
        }
        
        return null;
    }
}

 

 
posted @ 2015-09-17 14:48  Nily  阅读(597)  评论(0)    收藏  举报