完全二叉树的节点个数

一、需求

  • 给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数;
  • 完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置;

  • 若最底层为第 h 层,则该层包含 1~2^h 个节点;

     

输入:root = [1,2,3,4,5,6]
输出:6

提示:

  • 树中节点的数目范围是[0, 5 * 104]
  • 0 <= Node.val <= 5 * 104
  • 题目数据保证输入的树是 完全二叉树

进阶:遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?

二、前序遍历

2.1  思路分析

  1. 该题目只是统计完全二叉树中的节点个数,我们直接按二叉树来做,前序/中序/后序均可;

2.2  代码实现

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

2.3  复杂度分析

  • 时间复杂度为O(N);
  • 空间复杂度为O(N);

三、递归法

3.1  思路分析

  1. 我们可以将原问题:完全二叉树的节点个数转换为 1 + 左子树节点个数 + 右子树节点个数;
  2. 这次我们不用前序遍历,通过利用完全二叉树的性质来做,它有这样的情况:①它是一棵空树;②叶子节点只出现在最后两层,若最后一层不满,则叶子节点只出现在最左侧;
  3. 根据这样的性质,我们利用树的深度来计算节点个数,而不是遍历树的每一个节点,众所周知,当满二叉树的深度为 h 时,其节点个数为 2^h-1
  4. 我们求解当前节点左子树的深度leftTreeHeight和右子树的深度rightTreeHeight,存在两种情况:①leftTreeHeight == rightTreeHeight,那么左子树必然是满二叉树,加上当前节点,则深度为2^{leftTreeHeight},此时再加上右子树的节点数;②leftTreeHeight > rightTreeHeight,此时右子树必然是满二叉树,加上当前节点,则深度为2^{rightTreeHeight},再加上左子树的节点数;
  5. 关于如何求解树的深度,可以使用递归法,也可以根据完全二叉树的性质使用迭代,因此树的最大深度一定是由当前树最后一层的左子节点决定的,故只需遍历到最后一层最左侧的那个左子节点即可;

3.2  代码实现

class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }
       int leftTreeDepth = countDepth(root.left);
       int rightTreeDepth = countDepth(root.right);
       if(leftTreeDepth == rightTreeDepth) {
           return countNodes(root.right) + (1 << leftTreeDepth);
       } else {
           return countNodes(root.left) + (1 << rightTreeDepth);
       }
    }
    //该方法计算树的高度
    private int countDepth(TreeNode root) {
        int depth = 0;
        if(root == null) {
            return 0;
        }
        while(root != null) {
            depth++;
            root = root.left;
        }
        return depth;
    }
}

3.3  复杂度分析

  • 时间复杂度为O(log^2n)
  • 空间复杂度为O(1);

四、学习地址

作者:xiao-ping-zi-5

链接:https://leetcode-cn.com/problems/count-complete-tree-nodes/solution/chang-gui-jie-fa-he-ji-bai-100de-javajie-fa-by-xia/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值