222. 完全二叉树的节点个数——位运算

这篇博客详细介绍了如何使用C++实现一个二叉树的节点计数方法,通过遍历左子树确定树的层数,并结合二分查找找到节点总数。同时,辅助函数`isExist`用于判断指定位置的节点是否存在。算法实现了高效的时间复杂度,通过位运算加速了查找过程。
摘要由CSDN通过智能技术生成
class Solution {
public:
    int countNodes(TreeNode* root) {
        if(!root)
            return 0;
        TreeNode *node = root;
        int level = 0;
        //通过遍历左孩子可以得知二叉树层数
        while(node -> left){
            level++;
            node = node -> left;
        }
        //left是最后一层的最左节点, right是最底层理论上的最右节点
        int left = 1 << level, right = (1 << (level + 1)) - 1;
        //二分查找
        while(left < right){
            int mid = (right + left) / 2 + 1;   //left < right这里就要 + 1,防止left == right无限循环
            if(isExist(root, level, mid))
                left = mid; //因为存在,mid需要包含在内
            else
                right = mid - 1;    //不存在,mid不需要包含在内
        }
        //left == right 都是节点总数
        return left;
    }
    bool isExist(TreeNode* root, int level, int n){
        //涉及到位运算,例如1和5,1 == 1,6 == 110
        //每层的开头是 1, 10, 100, 1000
        //0代表左孩子,1代表右孩子,所以6是1的右孩子的左孩子
        //这样n从左往右看可以推出n所处的位置
        int bit = 1 << (level - 1); //因为第一位不看,所以要减一
        TreeNode* node = root;
        while(bit > 0 && node != nullptr){
            //bit一直是类100000的形式,计算bit的1对应的位置上是否为1
            if(bit & n) //为1,代表往右走
                node = node -> right;
            else    //为0,代表往左走
                node = node -> left;
            bit >>= 1;
        }
        return node != nullptr;
    }
};

Accepted
18/18 cases passed (32 ms)
Your runtime beats 47.66 % of cpp submissions
Your memory usage beats 95.22 % of cpp submissions (30 MB)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值