代码随想录第16天

104. 二叉树的最大深度

题目

在这里插入图片描述

题解

后序遍历

class Solution {
public:
    int depth(TreeNode* left,TreeNode*right,int depthCount)
    {
        if(right == NULL && left == NULL)
            return 0 + depthCount ;
        else if(right == NULL && left != NULL)
            return depth(left->left,left->right,depthCount) + depthCount + 1;
        else if(right != NULL && left == NULL)
            return depth(right->left,right->right,depthCount) + depthCount + 1;
        else
        {
            int leftDepth = depth(left->left,left->right,depthCount);
            int rightDepth = depth(right->left,right->right,depthCount);
            return max(leftDepth , rightDepth) + depthCount + 1;
        }
        
    }
    int maxDepth(TreeNode* root) {
        if(root == NULL)
            return 0;
        return depth(root->left,root->right,0) + 1;//传入迭代的是根节点的子节点,因此返回值也是子节点的深度,根节点需要+1
    }
};

better:

class solution {
public:
    int getdepth(treenode* node) {
        if (node == NULL) return 0;
        int leftdepth = getdepth(node->left);       // 左
        int rightdepth = getdepth(node->right);     // 右
        int depth = 1 + max(leftdepth, rightdepth); // 中
        return depth;
    }
    int maxdepth(treenode* root) {
        return getdepth(root);
    }
};

注意(后序遍历)

1.高度:叶子节点到该节点的路径上的节点数(后序遍历-左右中-先计算左右子节点的高度再计算父节点高度)
深度:根节点该叶子节点的路径上的节点数(前序遍历-中左右-先计算父节点深度再计算左右子节点深度)
根节点的高度就是二叉树的最大深度
2.每到一个中节点就要+1

111. 二叉树的最小深度

题目

在这里插入图片描述

题解

后序遍历

class Solution {
public:
    int depth(TreeNode* left,TreeNode*right,int depthCount)
    {
        if(right == NULL && left == NULL)
            return 0 + depthCount ;
        else if(right == NULL && left != NULL)
            return depth(left->left,left->right,depthCount) + depthCount + 1;
        else if(right != NULL && left == NULL)
            return depth(right->left,right->right,depthCount) + depthCount + 1;
        else
        {
            int leftDepth = depth(left->left,left->right,depthCount);
            int rightDepth = depth(right->left,right->right,depthCount);
            return min(leftDepth , rightDepth) + depthCount + 1;
        }
        
    }
    int minDepth(TreeNode* root) {
        if(root == NULL)
            return 0;
        return depth(root->left,root->right,0) + 1;
    }
};

注意

针对
针对图中的情况,按照 104. 二叉树的最大深度的better解法(max(leftdepth, rightdepth)改为min(leftdepth, rightdepth)),会导致计算结果为0,与题意不符

222. 完全二叉树的节点个数

题目

在这里插入图片描述

题解

后序遍历

class Solution {
public:
    int count(TreeNode* node)
    {
        if(node == NULL) return 0;
        int left = count(node->left);
        int right = count(node->right);
        return left + right + 1;
    }
    int countNodes(TreeNode* root) {
        if(root == NULL)    return 0;
        return count(root);
    }
};

层序遍历

class Solution {
public:
    int countNodes(TreeNode* root) {
        if(root == NULL)    return 0;
        int count = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            while(size--)
            {
                TreeNode* node = que.front();
                que.pop();
                count++;
                if(node->left)  que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return count;
    }
};

借助完全二叉树特性

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root == nullptr) return 0;
        TreeNode* left = root->left;
        TreeNode* right = root->right;
        int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
        while (left) {  // 求左子树深度
            left = left->left;
            leftDepth++;
        }
        while (right) { // 求右子树深度
            right = right->right;
            rightDepth++;
        }
        if (leftDepth == rightDepth) {
            return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
        }
        return countNodes(root->left) + countNodes(root->right) + 1;
    }
};

注意

1.左移n位表示乘以2的n次方,2左移n位表示2乘以2的n次方,即表示乘以2的(n + 1)次方
2.通过比较左节点数和右节点数可以判断是否为完全二叉树

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值