剑指 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)
    }
}
posted @ 2021-02-18 23:42  zjcfrancis  阅读(49)  评论(0编辑  收藏  举报