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)