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 }