剑指 Offer 68 - II. 二叉树的最近公共祖先
设节点 root 为节点 p, q 的某公共祖先,若其左子节点 root.left 和右子节点 root.right 都不是 p,q 的公共祖先,则称 root 是 “最近的公共祖先” 。
根据以上定义,若 root 是 p, q 的最近公共祖先 ,则只可能为以下情况之一:
p 和 q 在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);
p(q) = root,且 q(p) 在 root 的左或右子树中;
由此,可以用递归后序遍历,当遇到节点 p 或 q 时返回,再自底向顶回溯,返回值分四种情况:
1. left 和 right 同时为空,说明 root 的左右子树都不含 p、q,返回 null;
2. left 和 right 同时不为空,说明 p、q 分别位于 root 的左右子树,root 为最近公共祖先,返回 root;
3. left 为空,right 不为空,说明 p、q都在 root 的右子树,返回 right;
4. 同3.
代码如下:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root == null || root == p || root == q) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); if(left == null && right == null) return null; // 1. if(left == null) return right; // 3. if(right == null) return left; // 4. return root; // 2. if(left != null and right != null) } }