Lowest Common Ancestor of a Binary Search Tree(Java 递归与非递归)

题目描述:

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

  _______6______
       /              
    ___2__          ___8__
   /              /      
   0      _4       7       9
         /  
         3   5

For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.

解法一:

/**方法一
     * 
     * 给定一个二叉查找树(BST),寻找p和q的最小公共祖先结点
     * 解题思路:首先找到到达p的路径和到达q的路径,将这两个路径存入队列中
     * 然后对两个路径依次出队列,找出最后一组相同的结点,结束
     * @param root
     * @return
     */
    public static TreeNode lowestCommonAncestor(TreeNode root,TreeNode p,TreeNode q){
        if(root == null)
            return null;
        Queue<TreeNode> pPath = new LinkedList<TreeNode>();
        Queue<TreeNode> qPath = new LinkedList<TreeNode>();
        TreeNode pre = null;
        //返回true,说明该结点存在;否则,说明给定的结点不存在,则无需再比较
        if(findNode(root, p, pPath) && findNode(root, q, qPath)){
            while(!pPath.isEmpty() && !qPath.isEmpty()){
                TreeNode pNode = pPath.poll();
                TreeNode qNode = qPath.poll();
                if(pNode == qNode){ //记录最后一组相同结点
                    pre = pNode;
                } else { //一旦不同,跳出循环
                    break;
                }
            }
        }
        return pre;
    }
    
    /**
     * 在二叉树中查找结点p
     * 将其祖先结点依次存入队列
     * 返回true,说明该结点存在;否则,说明给定的结点不存在,则无需再比较
     * @param root
     * @param p
     * @param stack
     */
    public static boolean findNode(TreeNode root,TreeNode p,Queue<TreeNode> queue){ 
        if(root == null)
            return false;
        if(p.val == root.val){
            queue.add(root);
            return true;
        }
        else if(Integer.valueOf(p.val.toString()) < Integer.valueOf(root.val.toString())){ //在左子树查找
            queue.add(root);
            return findNode(root.left, p, queue);
        } 
        else {//在右子树查找
            queue.add(root);
            return findNode(root.right, p, queue);
        }
    }

解法二:

    /** 方法二
     * 
     * 递归算法
     * @param root
     * @param p
     * @param q
     * @return
     */
    public static TreeNode LCA(TreeNode root,TreeNode p,TreeNode q){
          if (root == null || p == null || q == null) return null;
          if (Integer.valueOf(p.val.toString()) < Integer.valueOf(root.val.toString()) && Integer.valueOf(q.val.toString()) < Integer.valueOf(root.val.toString())) //两个结点都在左子树
            return LCA(root.left, p, q);
          else if (Integer.valueOf(p.val.toString()) > Integer.valueOf(root.val.toString()) && Integer.valueOf(q.val.toString()) > Integer.valueOf(root.val.toString())) //两个结点都在右子树
            return LCA(root.right, p, q);
          else
            return root; //若两个结点一个在左子树上,另一个在右子树上,则共同祖先结点为当前的root
    }
原文地址:https://www.cnblogs.com/mydesky2012/p/5141766.html