LeetCode222:Count Complete Tree Nodes

Given a complete binary tree, count the number of nodes.

Definition of a complete binary tree from Wikipedia:

In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.


计算完全二叉树中节点的个数。

使用普通的遍历的方法就可以计算出节点的个数,但是这没有使用到完全二叉树的性质,事实也证明在leetcode中使用这种方式会导致超时。

百度百科中完全二叉树的定义如下:

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

根据完全二叉树的这个性质,可以这样来求解完全二叉树中节点的个数。

  1. 对于一个节点node,计算它最左端的节点到node的深度为leftDepth,计算它最右端的节点到node的深度是rightDepth;
  2. 如果leftDepth和rightDepth相等,那么以node为根节点的树是一棵满二叉树,此时以node为根节点的树的节点个数是pow(2,leftDepth)-1;
  3. 如果leftDepth和rightDepth不相等,递归求解node的左子树的节点数和右子树的节点数。注意此时左子树必定是满二叉树了。
从这道题中学到的一个很深的教训是对于树的问题,递归是一个很好的利器,因为树本身就是用递归来定义的。
runtime:168ms
/**
 * 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) {
        int res=0;
        helper(root,res);
        return res;
    }
    
    void helper(TreeNode * root,int &num)
    {
        if(root==NULL)
            return ;
            
        helper(root->left,num);
        num++;
        helper(root->right,num);
    }
    */
    
       int countNodes(TreeNode* root) {
           if(root==NULL)
                return 0;
                
            int leftDepth=0;
            int rightDepth=0;
            for(TreeNode* node=root;node!=NULL;node=node->left)
                leftDepth++;
            for(TreeNode* node=root;node!=NULL;node=node->right)
                rightDepth++;
            if(leftDepth==rightDepth)
                return (1<<leftDepth)-1;
            else
                return countNodes(root->left)+countNodes(root->right)+1;
       }
    

};



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值