问题描述:
给定一个“完全二叉树”(Complete Tree),问节点的个数。完全二叉树区别于“满二叉树”。Complete Tree的最后一层叶子节点可以不完全存在。也就是倒数第二层的节点不一定有两个孩子,但是这种。。。。说不明白,那直接看百度的定义:
完全二叉树:除最后一层外,每一层上的节点数均达到最大值;在最后一层上只缺少右边的若干结点。好吧,就是这样。
问题解决:
如图 我们可以给节点标号,起点是1,左孩子+0, 右孩子+1。eg:2 -> 10, 4 -> 100。 又由于这棵树节点最多也就是“满二叉树”的情况,也就是 pow(2, h) - 1个,所以我们通过这个性质得到节点数目的范围[1, pow(2, h) - 1]。
然后通过二分节点数目,然后在图中验证结果即可。总的复杂度:O(logn * logn)。这也算线性(linear)复杂度吧。
代码如下:
/** * 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 getHeight(TreeNode* root, int deep) { if(root == NULL) return deep; return getHeight(root -> left, deep + 1); } bool checkHaveIndex(TreeNode* root, int target, int curPos) { if(root){ if(curPos == 0) return true; int nextBit = target & (1 << (curPos - 1)); TreeNode *nextNode; if(nextBit == 0) root = root -> left; else root = root -> right; return checkHaveIndex(root, target, curPos - 1); } return false; } int getTheBinaryOnePos(int val) { for(int i = 31; i >= 0 ; i --){ if(val & (1<<i)){ return i; } } return 0; } int countNodes(TreeNode* root) { int h = getHeight(root, 0); int maxCnt = pow(2, h) - 1; int l = 0, r = maxCnt, m, ans = 0; while(l <= r){ m = (l + r)>>1; int onePos = getTheBinaryOnePos(m); if(checkHaveIndex(root, m, onePos)){ if(ans < m) ans = m; l = m + 1; }else{ r = m - 1; } } return ans; } };
我们都是蚂蚁,每天从床上爬起来,爬到食堂,爬到实验室,爬到食堂,爬到实验室,爬到食堂,爬到实验室,爬到寝室,爬到床上。。。