Leetcode---完全二叉树的节点个数

🌏生活,是一种缓缓如夏日流水般的前进,我们不要焦急。
在这里插入图片描述

题目描述

给你一棵完全二叉树的根节点 root ,求出该树的节点个数。完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
题目链接:https://leetcode-cn.com/problems/count-complete-tree-nodes/

解题思路:

对于任意二叉树,我们都可以使用广度优先搜索或深度优先搜索来计算节点的个数,时间复杂度和空间复杂度都是 O(n)。节点个数等于左子树个数+右子树个数+根结点个数。我们就可以得出如下代码
动图演示如下:
在这里插入图片描述

方法一:深度优先搜索计算节点个数

时间复杂度:O(n)【不考虑递归调用栈】
空间复杂度:O(n)

class Solution 
{
public:
    int countNodes(TreeNode* root) 
    {
        if(root==nullptr)	//如果为空,返回0
        {
            return 0;
        }
        //左子树个数+右子树个数+根结点
        return countNodes(root->left)+countNodes(root->right)+1;
    }
};

得出上述方法后,我们想想还有没有更优的方法呢?题目给的条件我们是否有全部用到呢?
这里我们发现题目中的一个题眼,那就是这个二叉树不是普通的二叉树,而是完全二叉树。
那么完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
我们知道完全二叉树最后一层节点的个数范围是在1~2^(k-1)之间。那么我们就可以利用满二叉树与完全二叉树的性质来优化代码。
针对情况一:若发现它的子树部分是满二叉树,直接返回该子树的结点个数 。结点个数等于
2^(k-1)

针对情况二:分别递归左、右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
动画演示如下:
在这里插入图片描述
根据上面的情况,我们可以写出如下方法二的解法。

方法二:根据完全二叉树的性质简化遍历次数

时间复杂度:O(logn * logn) 【不考虑递归调用栈】
空间复杂度:O(logn)

class Solution 
{
public:
    
    int countNodes(TreeNode* root) 
    {
        if(root==nullptr)
        {
            return 0;
        }
        int leftdepth=0;	//存储最左子树深度
        int rightdepth=0;	//存储最右子树深度
        TreeNode*left=root->left;
        TreeNode*right=root->right;
        while(left!=nullptr)    //得到左子树的深度
        {
            ++leftdepth;
            left=left->left;
        }
        while(right!=nullptr)   //得到右子树的深度
        {
            ++rightdepth;
            right=right->right;
        }
        if(leftdepth==rightdepth)   //判断该子树部分是不是满二叉树,是就返回它的个数
        {
            return (2<<leftdepth)-1;
        }
        return countNodes(root->left)+countNodes(root->right)+1;
    }
};

总结

1、由于树比较复杂,每当我们使用时都要注意边界条件的检查,即检查空指针。
2、我们在遍历树的代码中一旦要高度警惕,在每一处需要访问地址的时候都要问自己这个地址有没有可能是nullptr,如果是nullptr我们应该怎么处理。

在这里插入图片描述
如有错误之处或有更优解,还请各位指出,谢谢大家!!!
END…

LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值