标签:
找binary tree中两个node第一个公共祖先。注意不一定是BST
1 public static TreeNode commonAncestor2(TreeNode root, TreeNode p, TreeNode q) { 2 if (!covers(root, p) || !covers(root, q)) { // Error check - one node is not in tree 3 return null; 4 } 5 return helper(root, p, q); 6 } 7 private static TreeNode helper(TreeNode root, TreeNode p, TreeNode q){ 8 if(root == null) return null; 9 10 boolean is_p_on_left = covers(root.left, p); 11 boolean is_q_on_left = covers(root.left, q); 12 13 if(is_p_on_left != is_q_on_left){ 14 //nodes are on different side 15 return root; 16 } 17 TreeNode child_side = is_p_on_left ? root.left : root.right; 18 19 //search in subtree 20 return helper(child_side, p, q); 21 22 23 } 24 //check whether p is a descendent of root 25 private static boolean covers(TreeNode root, TreeNode p){ 26 if(root == null) return false; 27 28 if(root == p) return true; 29 30 return covers(root.left, p) || covers(root.right, p); 31 }
类似解法 http://xixiaogualu.blogspot.com/2013/09/lowest-common-ancestor-of-binary-tree.html
top - bottom自顶向下:
public static TreeNode LCA1(TreeNode root,TreeNode n1,TreeNode n2){ if(exist(root.left,n1) && (exist(root.left,n2))){ //find in left subtree return LCA1(root.left, n1, n2); } if(exist(root.right,n1)&&(exist(root.right,n2))){ return LCA1(root.right, n1, n2); } return root; } //find in subtree from root public static boolean exist(TreeNode root, TreeNode n){ if(root == n) return true; if(root == null) return false; return exist(root.left,n)||exist(root.right,n); }
Solution2:改进上面解法 from cc150
Bottom-up ,利用commonAncestor的返回值减少向下search次数,递归调用。
返回值可能的几种情况为:
1 public static TreeNode LCA(TreeNode root, TreeNode p, TreeNode q){ 2 if(root == null) return null; 3 if(root == p || root == q){ 4 5 return root; 6 } 7 8 //are child of root 9 if(p == root.left && q == root.right || p == root.right && q == root.left){ 10 return root; 11 } 12 13 //search in left and right subtree 14 TreeNode left = LCA(root.left, p, q); 15 TreeNode right = LCA(root.right, p, q); 16 17 if(left != null && right != null){ 18 //one is in left subtree and the other is in right 19 return root; 20 } 21 if(left != null){ 22 return left; 23 } 24 if(right != null){ 25 return right; 26 } 27 return null; 28 }
拓展: 如果可能p或者q为不在tree里的node,上面bottom up的方法就会产生问题
class Result{ public TreeNode node; public boolean isAncestor; public Result(TreeNode n, boolean isAnc){ node = n; isAncestor = isAnc; } }
public static TreeNode commonAncestor3(TreeNode root, TreeNode p, TreeNode q) { Result res = helper(root, p, q); if(res.isAncestor){ return res.node; } return null; }
1 private static Result helper(TreeNode root, TreeNode p, TreeNode q){ 2 if(root == null){ 3 return new Result(null, false); 4 } 5 if(root == p && root == q){ 6 return new Result(root, true); 7 } 8 9 Result left = helper(root.left, p, q); 10 if(left.isAncestor){ 11 return left; 12 } 13 Result right = helper(root.right, p,q); 14 if(right.isAncestor){ 15 return right; 16 } 17 //find common ancestor 18 if(left.node != null && right.node != null){ 19 return new Result(root, true); 20 }else if(root == p || root == q){ 21 /* If we’re currently at p or q, and we also found one of those 22 nodes in a subtree, then this is truly an ancestor and the 23 flag should be true. */ 24 boolean isAncestor = left.node != null || right.node != null; 25 return new Result(root, isAncestor); 26 }else{ 27 // 28 return new Result(left.node != null ? left.node : right.node, false); 29 } 30 }
标签:
原文地址:http://www.cnblogs.com/xiaomaoliu/p/4475187.html