详见:lowest common ancestor of binary tree
A Bottom-up Approach (Worst case O(n) ):
Using a bottom-up approach, we can improve over the top-down approach by avoiding traversing the same nodes over and over again.
We traverse from the bottom, and once we reach a node which matches one of the two nodes, we pass it up to its parent. The parent would then test its left and right subtree if each contain one of the two nodes. If yes, then the parent must be the LCA and we pass its parent up to the root. If not, we pass the lower node which contains either one of the two nodes (if the left or right subtree contains either p or q), or NULL (if both the left and right subtree does not contain either p or q) up.
Sounds complicated? Surprisingly the code appears to be much simpler than the top-down one.
Node *LCA(Node *root, Node *p, Node *q) {
if (!root) return NULL;
if (root == p || root == q) return root;
Node *L = LCA(root->left, p, q);
Node *R = LCA(root->right, p, q);
if (L && R) return root; // if p and q are on both sides
return L ? L : R; // either one of p,q is on one side OR p,q is not in L&R subtrees
}
如果p和q分别在公共祖先的左子树和右子树,那么上面的代码会找到这个祖先节点。
如果p就是q的祖先节点,那么上面的代码在找到节点p之后,就不会再继续往下走了,这个时候会直接返回节点p。
作为思考题,想一想把第3行代码 if (root == p || root == q) return root 放在 Node *R = LCA(root->right, p, q) 后面会有什么结果?