222. 完全二叉树的节点个数
思路1
可以直接递归求解
代码1
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int countNodes(TreeNode* root) {
return root==nullptr?0:1+countNodes(root->left)+countNodes(root->right);
}
};
思路2
先求出树的最大深度,对树的最深层进行二分法查找,看看mid这个节点是否存在,算法的时间复杂度为O(log²n)。
位运算符介绍
A = 0011 1100
B = 0000 1101
运算符 | 描述 | |
---|---|---|
& | 对每一位求与 | A&B = 0000 1100 = 12 |
| | 对每一位求或 | A|B = 0011 1101 = 61 |
^ | 对每一位求异或 | |
~ | 对每一位求非 | |
<< | 向左移位,相当于*2 | |
>> | 向右移位,相当于/2 |
详细请看 菜鸟教程-C++运算符
代码2
这里直接放个LeetCode的官方题解
举例说明 bits & k的用法
level = 3(root为第零层)
第3层最小的数为 1(0001) 最大的数为 8(1000)
bits = 4(0100)
假设k =5(0101) k&bits = 4(0100) 表示左子树是满的,应该看右子树
假设k =3(0011) k&bits = 0(0000) 表示左子树没有满,应该看左子树
bits>>1 = 是因为二分法,排除掉了一般的数了,中间数也要除以2。
这样就能通过改变bits中1的位置,来找到k代表的结点了,判断该结点是否为空。
while (low < high) {
int mid = (high - low + 1) / 2 + low;
if (exists(root, level, mid)) {
low = mid;
} else {
high = mid - 1;
}
}
bool exists(TreeNode* root, int level, int k) {
int bits = 1 << (level - 1);
TreeNode* node = root;
while (node != nullptr && bits > 0) {
if (!(bits & k)) {
node = node->left;
} else {
node = node->right;
}
bits >>= 1;
}
return node != nullptr;
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/count-complete-tree-nodes/solution/wan-quan-er-cha-shu-de-jie-dian-ge-shu-by-leetco-2/
来源:力扣(LeetCode)