转自:Pavel's Blog
1 public static Node lowestCommonAncestor(Node root, Node a, Node b) { 2 if (root == null) { 3 return null; 4 } 5 6 if (root.equals(a) || root.equals(b)) { 7 // if at least one matched, no need to continue 8 // this is the LCA for this root 9 return root; 10 } 11 12 Node l = lowestCommonAncestor(root.left, a, b); 13 Node r = lowestCommonAncestor(root.right, a, b); 14 15 if (l != null && r != null) { 16 return root; // nodes are each on a seaparate branch 17 } 18 19 // either one node is on one branch, 20 // or none was found in any of the branches 21 return l != null ? l : r; 22 }
For the node used we will use the following class:
1 public class Node { 2 public int data; 3 public Node right; 4 public Node left; 5 6 public Node(int data) { 7 this.data = data; 8 } 9 }
这个问题再follow up一下,就是要找到shortest path in a binary tree between two nodes
1 public class Solution { 2 public static List<Node> shortestPath(Node root, Node a, Node b) { 3 ArrayList<Node> path1 = new ArrayList<Node>(); 4 ArrayList<Node> path2 = new ArrayList<Node>(); 5 Node LCA = lowestCommonAncestor(root, a, b); 6 helper(LCA.left, a, b, path1, new ArrayList<Node>()); 7 helper(LCA.right, a, b, path2, new ArrayList<Node>()); 8 Collections.reverse(path1); 9 path1.add(LCA); 10 path1.addAll(new ArrayList<Node>(path2)); 11 return path1; 12 } 13 14 public void helper(Node root, Node a, Node b, ArrayList<Node> outpath, ArrayList<Node> temp) { 15 if (root == null) return; 16 temp.add(root); 17 if (root == a || root == b) { 18 outpath = new ArrayList<Node>(temp); 19 return; 20 } 21 helper(root.left, a, b, outpath, temp); 22 helper(root.right, a, b, outpath, temp); 23 temp.remove(temp.size()-1); 24 } 25 }
别人的Stack做法,未深究 他说First stack is not really needed, a simple list would do - I just like symmetry.
1 public static <V> void shortestpath( 2 Node<V> root, Node<V> a, Node<V> b, 3 Stack<Node<V>> outputPath) { 4 if (root == null) { 5 return; 6 } 7 if (root.data.equals(a.data) || root.data.equals(b.data)) { 8 outputPath.push(root); 9 return; 10 } 11 12 shortestpath(root.left, a, b, outputPath); 13 shortestpath(root.right, a, b, outputPath); 14 15 outputPath.push(root); 16 } 17 18 public static List<Node> shortestPath(Node root, Node a, Node b) { 19 Stack<Node> path1 = new Stack<>(); 20 Stack<Node> path2 = new Stack<>(); 21 22 Node lca = lowestCommonAncestor(root, a, b); 23 24 // This is to handle the case where one of the nodes IS the LCA 25 Node r = lca.equals(a) ? a : (lca.equals(b) ? b : lca); 26 27 shortestpath(r.left, a, b, path1); 28 shortestpath(r.right, a, b, path2); 29 30 path1.push(r); 31 // invert the second path 32 while (!path2.isEmpty()) { 33 path1.push(path2.pop()); 34 } 35 return path1; 36 }