/// <summary> /// Find the common ancestor to two nodes. The ancestor of the root node is itself.(!) /// </summary> /// <param name="root"></param> /// <param name="n1"></param> /// <param name="n2"></param> /// <returns></returns> public static lcaResult lca_func(TreeNode root, TreeNode n1, TreeNode n2) { if (root == null) { return(new lcaResult(0, null)); } // recursively investigate left subtree lcaResult leftResult = lca_func(root.left, n1, n2); if (leftResult.nodesFound == 2) { return(leftResult); } // recursively investigate right subtree lcaResult rightResult = lca_func(root.right, n1, n2); if (rightResult.nodesFound == 2) { return(rightResult); } // if we got to this point, then: // - the common ancestor is not in the left subtree, otherwise nodesFound == 2 would have been true earlier // - ditto // if one of the nodes is in the left subtree, and the other is in the right subtree, then the current root // node is the common ancestor we're looking for. int nodesFound = leftResult.nodesFound + rightResult.nodesFound; if (root == n1) { nodesFound++; } if (root == n2) { nodesFound++; } if (nodesFound == 2) { return(new lcaResult(2, root)); } return(new lcaResult(nodesFound, null)); }
public static TreeNode lca(TreeNode root, TreeNode n1, TreeNode n2) { // special cases: // root == n1, and/or root == n2 if (root == n1 || n1 == n2) { return(root); } if (root == null) { return(null); } lcaResult lcaData = lca_func(root, n1, n2); return(lcaData.ancestor); }