树的深度相关题目

树的深度相关题目

以二叉树为例:

struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
};

二叉树的深度

思路:
对于根节点来说,就是左右子树中最深的加一。递归的来说,对于当前节点的深度,是其左右子树的最大深度加一,递归边界为(-1),考虑叶节点深度为1,所以空节点为0,即递归边界为0。
代码:

int TreeDepth(TreeNode* root)
{
    //递归边界
    if(!root) return 0;
    
    int leftDepth = TreeDepth(root->left);
    int rightDepth = TreeDepth(root->right);
    
    return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
}

二叉树的直径(即相距最远的两个叶子节点)

错误的思路:将根节点左右子树分离,分别递归的求左右子树的深度然后加和再+2即可,但是下面这种情况显然不是:

正确的思路(附带递归的思考方法):

  • 1.传入一个外部引用,用来记录最远距离。
  • 2.先考虑根节点计算通过根节点的两个叶节点的最远距离,然后与已经记录的最远距离做比较。(这是较直观的思考递归的方法,先看根节点,再将根节点“泛化”为任意当前节点来考虑)
  • 3.同理递归的考虑当前节点,其中通过当前节点的相距最远的两个叶节点的距离,是左右子树的深度+2,因此相对于当前节点递归返回其左右子树的最大深度即可,因此递归边界(要结合返回值以及函数功能来考虑)为-1,因为叶节点到其父节点的距离为1,因此叶节点要初始化为0,故递归至空节点(递归边界)时返回0.

代码:

int Dis(TreeNode* root,int& maxDis)
{
    if(!root) reutn -1;
    int leftD = Dis(root->left, maxDis) + 1;
    int rightD = Dis(root->left, maxDis) +1;
    
    int dist = leftD + rightD;
    maxDis = (maxDis > dist ? maxDis : dist);
    
    return (leftD > rightD ? leftD : rightD);
}

判断是否为平衡二叉树

平衡二叉树的定义:任何节点的两颗子树的高度差不能大于一(明显涉及深度问题)

思路:
1.确定函数结构,判断是否为平衡二叉树,故返回值为bool,传入参数为树的根节点,因为要用到深度,所以要额外调用上文的二叉树深度函数。为了面向对象编程,可将其封装成类即:

class solution{
public:
int TreeDepth(TreeNode* root);
bool isBalanced(TreeNode* root);
};

2.先直观考虑根节点,判断其左右子树的高度差不大于一,即需要求左右子树的深度。
3.然后递归的去判断左右子树(递归一开始上述的直观考虑根节点,即被泛化为任意节点)
4.空节点被认为是平衡而c二叉树,因此递归边界返回true;

TreeDepth代码上文有,此处省略,代码一如下:

bool isBalanced(TreeNode* root)
{
    if(!root) return true;
    
    return (abs(TreeDepth(root->left) - TreeDepth(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right));
    
}

上述代码虽然简洁易懂,很明显的一个缺点是对于任意节点都要递归求解其深度,为了解决这个问题我们可以传入一个外部引用,记录已经求解的深度。传入外部引用的好处可以让函数多了个”返回值“。

上述代码是从根节点向下递归,每次都递归求解深度,下面的思路是通过叶节点的深度(递归边界)层层向上叠加

class solution{
public:
    bool isBalanced(TreeNode* root);
    bool isBalanced(TreeNode* root, int& depth);
};

代码二:

class solution{
public:
    bool isBalanced(TreeNode* root)
    {
        int depth = 0;
        return isBalanced(root, depth);
    }
    bool isBalanced(TreeNode* root, int& depth){
        if(!root) 
        {
            depth = 0;
            return true;
        }
        //可额外增加此判断代码节省用时,不加也可以
        if(!root->right && !root->right)
        {
            deoth = 1;
            return true;
        }
        
        int leftD = 0;
        int rightD = 0;
        bool b1 = isBalanced(root->left, leftD);
        bool b2 = isBalanced(root->right,rightD);
        depth = (leftD > rightD ? leftD : rightD) + 1;
        if(abs(leftD - rightD) <= 1)
            return b1&b2;
        return false;    
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值