2021-03-09 具有所有最深节点的最小子树

题目 具有所有最深节点的最小子树

给定一个根为 root 的二叉树,每个节点的深度是 该节点到根的最短距离 。
如果一个节点在 整个树 的任意节点之间具有最大的深度,则该节点是 最深的 。
一个节点的 子树 是该节点加上它的所有后代的集合。
返回能满足 以该节点为根的子树中包含所有最深的节点 这一条件的具有最大深度的节点。

示例 1:
在这里插入图片描述
输入:root = [3,5,1,6,2,0,8,null,null,7,4]
输出:[2,7,4]
解释:
我们返回值为 2 的节点,在图中用黄色标记。
在图中用蓝色标记的是树的最深的节点。
注意,节点 5、3 和 2 包含树中最深的节点,但节点 2 的子树最小,因此我们返回它。

示例 2:
输入:root = [1]
输出:[1]
解释:根节点是树中最深的节点。

示例 3:
输入:root = [0,1,3,null,2]
输出:[2]
解释:树中最深的节点为 2 ,有效子树为节点 2、1 和 0 的子树,但节点 2 的子树最小。

  1. 设置两个全局变量:MaxHeight,记录最深深度;pNode,记录所求结点
  2. 通过调用函数getSolution,传入两个参数:root表示当前结点,height表示当前结点的高度
  3. 求左右子树的高度left、right
  4. 如果左右子树高度一样,则分两种情况
    a. 叶子节点:则比较该节点的深度和最深深度MaxHeight,判断是否是最深深度结点
    b. 非叶子结点:则判断该子树的最深深度是否为整棵树的最深深度,即判断该节点高度height+子树深度left是否等于MaxHeight,等于则所求结点pNode
class Solution {
public:
    TreeNode* pNode = NULL;
    int MaxHeight = 0;
public:
    TreeNode* subtreeWithAllDeepest(TreeNode* root) {
    	//如果根节点为NULL或一个结点
        if(!root || (!root->left && !root->right)) return root;
        getSolution(root,0);
        return pNode;
    }
    int getSolution(TreeNode* root,int height)
    {
    	//求左子树、右子树的深度left、right
        int left,right;
        left = right = 0;
        if(root->left) left = getSolution(root->left,height+1);
        if(root->right) right = getSolution(root->right,height+1);
        //如果左右子树深度一样,则有两种情况
        if(left == right)
        {
        	//1. 叶子结点,则判断该节点深度是否大于最深深度,是则pNode赋值该节点并更新最深深度
            if(left == 0 && height > MaxHeight)
            {
                pNode = root;
                MaxHeight = height;
            }
            //2. 父亲结点,则其孩子的最深深度为height+子树高度,判断深度是否为最深深度,是则说明该节点是所有最深结点的组合最小子树的根
            else if(left > 0 && height+left == MaxHeight)
                pNode = root;
        }
        //返回深度+1
        return max(left , right)+1; 
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值