LeetCode 222. 完全二叉树的节点个数

题目描述:

给出一个完全二叉树,求出该树的节点个数。

说明:

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

示例:

输入: 
    1
   / \
  2   3
 / \  /
4  5 6

输出: 6

思路:这个解题方法是来自于leetCode上一个解法。主要思想是计算出树的高度,然后统计出叶子节点的数目,然后利用公式 nodenums=2^(height-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 getHeight(TreeNode *root)
    {
        int height = 1;
        while(root->left != NULL)
        { 
            height++; 
            root = root->left;}
        return height;
    }
  
    int countNodes(TreeNode* root) {
        if(root == NULL) 
            return 0;
        
        int height = getHeight(root);
        
        //利用变形的二分法来计算叶子节点的个数
        int leafCnt=0;
        int level=height-2;
        TreeNode *cur=root;
        while(level>=0)
        {
            TreeNode *temp=cur->left;
            for(int i=0; i<level;++i)
                temp=temp->right;//找到最后一个right
            if(temp){//判断是否存在,如果存在这一层前半部分的叶子节点肯定是存在的,然后就可以从当前cur的右边看右边是否存在叶子节点
                leafCnt+=1<<level;
                cur=cur->right;
            } 
            else
                cur=cur->left;
            
            level--;
        }
        
        if(cur)//是否存在最后一个单独的节点
            leafCnt++;
        
        return (1<<height-1)-1+leafCnt;//左移和右移运算符优先级很低,注意加括号
    }

};



输入: 
    1
   / \
  2   3
 / \  /
4  5 6

输出: 6

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值