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

题目

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

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

题目链接:完全二叉树节点个数

思路

首先想到直接递归求解,这种解法适合于各类完全二叉树,代码如下:

class Solution {
    public int countNodes(TreeNode root) {
        if (root==null) return 0;
        return countNodes(root.left) + countNodes(root.right)+1;
    }
}

题目强调完全二叉树,则可以想办法利用其性质,加速或者更巧妙求解。
我们知道满二叉树的节点个数为 2 H e i g h t − 1 2^{Height}-1 2Height1;对于完全二叉树的根节点root,有两种情况:

  • 左子树为满二叉树,右子树不是
  • 左子树不是满二叉树,则根据其是完全二叉树,可以得知,右子树必为满二叉树

因此我们的思路为计算左右子树的高度,如果他们高度相等,则为情况1,否则为情况2。

对于情况1,左子树的节点个数为( 2 l e f t H e i g h t − 1 2^{leftHeight}-1 2leftHeight1
,右子树的节点个数可以由递归计算,即当前根节点更新为root.right,因此总的节点个数(包括了根节点)为 2 r i g h t H e i g h t − 1 2^{rightHeight}-1 2rightHeight1+1+countNodes(root.right)

对于情况2,右子树的节点个数为( 2 r i g h t H e i g h t − 1 2^{rightHeight}-1 2rightHeight1),左子树的节点可以由递归计算,总的节点个数为 2 r i g h t H e i g h t − 1 2^{rightHeight}-1 2rightHeight1+1+countNodes(root.left)

这里计算2的次方,可以采用位运算,即(1<<Height, 相当于01B,左移Height次)

网友评论: 本质就是二分查找,比较左右两颗子树的高度:
1.如果当前节点左右子树高度相等:当前节点的左子树就是一颗满二叉树,可以直接计算左子树节点个树为:2的左子树高度次方。总的节点个树,则只需再加上右子树的节点树。把右子节点树继续递归求解。
2.如果当前节点左右子树高度不相等:则左子树可能不是满二叉树,且右子树是满二叉树,则利用右子树高度就可以求出右子树节点个树。此时只需继续递归求解左子树,就可以得到总节点树。

代码

class Solution {
    public int countNodes(TreeNode root) {
        if (root==null) return 0;
        int leftL = countLevel(root.left);
        int rightL = countLevel(root.right);
        if (leftL==rightL){
            return countNodes(root.right) + (1<<leftL);
        } else {
            return countNodes(root.left) + (1<<rightL);
        }
    }

    public int countLevel(TreeNode root){
        int level = 0;
        while(root!=null){
            //利用完全二叉树的特性计算层数
            level++;
            root = root.left;
        }
        return level;
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值