【Leetcode】222. Count Complete Tree Nodes

问题描述:

  给定一个“完全二叉树”(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;
    }
};

我们都是蚂蚁,每天从床上爬起来,爬到食堂,爬到实验室,爬到食堂,爬到实验室,爬到食堂,爬到实验室,爬到寝室,爬到床上。。。

 

posted on 2016-04-19 10:05  暴力的轮胎  阅读(258)  评论(0编辑  收藏  举报

导航