剑指Offer 面试题68 - II. 二叉树的最近公共祖先(Java代码)

文章目录

      • 题目
      • 题解

题目

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
剑指Offer 面试题68 - II. 二叉树的最近公共祖先(Java代码)_第1张图片
2 和 5 的最近公共祖先是 5
6 和 8 的最近公共祖先是 3

题解

通过深度优先搜索的方式,遍历二叉树,如果找到了相等节点,就立即返回(此时这个节点可能是公共祖先,也可能是其中一个节点),否则返回null

  • 如果出现相等节点的子树的父节点的另一个子树中,也出现了非null的返回值,说明父节点是公共祖先
  • 否则,由于父节点的另一个子树返回的是null,所以需要继续将此节点向上返回(因为此节点可能是公共祖先)
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 如果是叶子节点的子树(返回null);或者是目标节点中的一个(返回 非null)
        if(root == null || root == p || root == q) return root;
        // 使用后序遍历得到递归的返回值
        root.left = lowestCommonAncestor(root.left, p, q);
        root.right = lowestCommonAncestor(root.right, p, q);
        // 如果两个子树返回值都不是null,说明父节点是公共祖先
        if(root.left != null && root.right != null) return root;
        // 由于叶子节点的两个子树都返回null,所以叶子节点返回null,另一片叶子节点如果也是都返回null,那么两片叶子节点的父节点也会向上返回null =====> 所以只要左右子树中没有目标节点,那么左右子树最终都会返回null。
        // 相反只要有一个返回非null,就将非null向上返回
        return (root.left == null) ? root.right : root.left;
    }
}

记得递归之后,要重新给 root.left 和 root.right 赋值!!!!!!!!!!!!!!!!!!!!!!!

你可能感兴趣的:(剑指Offer)