leetcode_865. Smallest Subtree with all the Deepest Nodes

https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/

给定一颗二叉树,输出包含所有最深叶子结点的最小子树的根节点。

解法一:

先使用dfs计算最大深度deep和最大深度的叶子结点数cnt,然后后序遍历,对每个节点再使用dfs计算以该节点为根节点的子树中所含最大深度的节点数,最先找到的最大深度为节点数目等于cnt的节点即为答案。

class Solution{
public:
    int deep=-1,cnt=0;
    TreeNode* res=NULL;
TreeNode
* subtreeWithAllDeepest(TreeNode* root){ cntdeepest(root, 0); backorder(root, 0); return res; } void cntdeepest(TreeNode * root, int d){ if(d>deep){ deep=d; cnt=1; }else if(d==deep) cnt++; if(root->left != NULL) cntdeepest(root->left,d+1); if(root->right != NULL) cntdeepest(root->right, d+1); } void backorder(TreeNode* root, int d){ if(root == NULL) return; if(res != NULL) return; backorder(root->left, d+1); backorder(root->right, d+1); int all = calcdeepest(root, d); if(res==NULL && all == cnt) res = root; } int calcdeepest(TreeNode* root, int d){ if(root == NULL) return 0; if(d == deep) return 1; int left=0, right=0; if(root->left != NULL) left = calcdeepest(root->left, d+1); if(root->right != NULL) right = calcdeepest(root->right, d+1); int all = left+right; return all; } };

这种解法若节点数过多,会比较费时。

 

解法二:官方题解

dfs(TreeNode* root, depth)返回以root为根节点的子树中包含该子树上所有深度最深叶节点的指针和最大深度。

若为子节点,返回其指针和深度。

若左子树的深度大于右子树,说明只有左子树中包含深度最大的叶节点。

若其中一个子树为空,说明另外一棵子树包含着深度最深的节点。

若两子树深度相同,说明该节点是当前包含该子树上所有深度最深节点的最小子树根节点。

struct Return{
    TreeNode* root_;
    int depth_;
    Return(TreeNode* root, int depth):root_(root),depth_(depth){}
};

class Solution {
public:
    TreeNode* subtreeWithAllDeepest(TreeNode* root) {
        Return ret = dfs(root, 0);
        return ret.root_;
    }
    Return dfs(TreeNode* root, int depth){
        if(root == NULL)
            return Return(NULL, 0);
        if(root->left == NULL && root->right == NULL)
            return Return(root, depth);
        Return left = dfs(root->left, depth+1);
        Return right = dfs(root->right,depth+1);
        if(left.root_ == NULL && right.root_ == NULL)  //叶节点
            return Return(root, depth);
        else if(left.root_ == NULL)                    //左子树为空的中间节点
            return right;
        else if(right.root_ == NULL)                   //右子树为空的中间结点
            return left;
        else if(left.depth_ == right.depth_)
            return Return(root, left.depth_);
        else
            return left.depth_>right.depth_?left:right;
    }
};

 

转载于:https://www.cnblogs.com/jasonlixuetao/p/10585374.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值