二叉树的最近公共祖先

1 二叉树递归灵魂三问

  • 这个函数应该干什么?
    • 函数功能
    • 正向逻辑推理
  • base case是啥?
  • 得到递归结果后,会做什么?
    • 反向逻辑推理

下面使用一个题目来示例一下。



2 题目

2.1 236. 二叉树的最近公共祖先

2.1.1 题目

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

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

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

示例 1:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

示例 2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

2.1.2 思路

由于是一个二叉树的题目,直接写上二叉树框架应该没有问题。

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
    }
}

下面开始灵魂三问

2.1.2.1 这个函数应该干什么?

函数功能:找出以根节点root的树下节点pq的最近公共祖先节点,并返回公共祖先节点。

根据函数功能进行正向逻辑推理(这里不要把root认为是最大范围的根节点):

  • pq都在root下,返回rootpq的最近公共祖先节点。
  • pq都不在root下,返回null
  • pq只有一个在root下,返回root

2.1.2.2 base case是啥?

  • root == null时,返回null
  • p == root || q == root时,返回root

2.1.2.3 得到递归结果后,会做什么?

根据递归结果进行反向逻辑推理(这里把root认为是最大范围的根节点,不要陷入递归)

  • leftright均不为空,则root为最近公共祖先节点。
  • leftright均为空,则没有最近公共祖先节点。
  • left != null && right == null,返回left。相反的情况,返回 right

然后就不要想这么多了,先把代码写上吧!如果出错,肯定是三个问题哪里没有答好,就要回去再仔细思考一下,看看有没有漏,记住回去想的时候最好避免陷入递归里面去想

2.1.3 代码

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) return null;
        if (p == root || q == root) return root;
        
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left != null && right != null) {
            return root;
        }
        if (left == null && right == null) {
            return null;
        }
        return left != null ? left : right;
    }
}

3 参考

posted @ 2020-12-24 23:07  Cigar丶  阅读(153)  评论(0编辑  收藏  举报